diff --git a/cave/com.raytheon.uf.viz.archive.feature/feature.xml b/cave/com.raytheon.uf.viz.archive.feature/feature.xml index a6e02ec615..5196e8495f 100644 --- a/cave/com.raytheon.uf.viz.archive.feature/feature.xml +++ b/cave/com.raytheon.uf.viz.archive.feature/feature.xml @@ -1,7 +1,7 @@ @@ -36,4 +36,11 @@ version="0.0.0" unpack="false"/> + + diff --git a/cave/com.raytheon.uf.viz.archive/META-INF/MANIFEST.MF b/cave/com.raytheon.uf.viz.archive/META-INF/MANIFEST.MF index 5da8bf4ad4..38169b5423 100644 --- a/cave/com.raytheon.uf.viz.archive/META-INF/MANIFEST.MF +++ b/cave/com.raytheon.uf.viz.archive/META-INF/MANIFEST.MF @@ -7,11 +7,14 @@ Bundle-Activator: com.raytheon.uf.viz.archive.Activator Bundle-Vendor: RAYTHEON Require-Bundle: org.eclipse.ui;bundle-version="3.8.2", org.eclipse.core.runtime, + org.apache.commons.lang;bundle-version="2.3.0", com.raytheon.viz.ui;bundle-version="1.12.1174", com.raytheon.uf.common.serialization;bundle-version="1.12.1174", com.raytheon.uf.common.localization;bundle-version="1.12.1174", com.raytheon.uf.common.archive;bundle-version="1.0.0", com.raytheon.uf.common.time;bundle-version="1.12.1174", - com.raytheon.uf.common.util;bundle-version="1.12.1174" + com.raytheon.uf.common.util;bundle-version="1.12.1174", + com.raytheon.uf.viz.core;bundle-version="1.12.1174", + com.raytheon.uf.common.units;bundle-version="1.0.0" Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Bundle-ActivationPolicy: lazy diff --git a/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/RetentionHours.java b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/RetentionHours.java deleted file mode 100644 index f2c61e53c2..0000000000 --- a/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/RetentionHours.java +++ /dev/null @@ -1,108 +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; - -import com.raytheon.uf.common.time.util.TimeUtil; - -/** - * Convenience class for taking retention hours and converting to days/hours. - * - *
- * 
- * SOFTWARE HISTORY
- * 
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * May 2, 2013  1966       rferrel     Initial creation
- * 
- * 
- * - * @author rferrel - * @version 1.0 - */ - -public class RetentionHours { - - private int retentionHours; - - /** - * Constructor with default 7 day retention. - */ - public RetentionHours() { - this(7 * TimeUtil.HOURS_PER_DAY); - } - - /** - * Constructor specify retention hours. - * - * @param retentionHours - */ - public RetentionHours(int retentionHours) { - this.retentionHours = retentionHours; - } - - /** - * Set retention to this number of days. - * - * @param days - */ - public void setDays(int days) { - retentionHours = days * TimeUtil.HOURS_PER_DAY; - } - - /** - * Convert retention hours to days. Note values are truncated so a retention - * of 23 hours will return 0 days. - * - * @return days - */ - public int getDays() { - return retentionHours / TimeUtil.HOURS_PER_DAY; - } - - /** - * Get retention in hours. - * - * @return - */ - public int getHours() { - return retentionHours; - } - - /** - * Set number hours of retention. - * - * @param hours - */ - public void setHours(int hours) { - retentionHours = hours; - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - return "RetentionHours [days:" + getDays() + ", hours:" + getHours() - + "]"; - } -} diff --git a/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/data/ArchiveInfo.java b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/data/ArchiveInfo.java new file mode 100644 index 0000000000..6391f7a2d9 --- /dev/null +++ b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/data/ArchiveInfo.java @@ -0,0 +1,62 @@ +/** + * 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.archive.data; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +/** + * This class maintains the state of the archive selection so it can be restored + * by the GUI. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 24, 2013 1966       rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ + +public class ArchiveInfo { + private final Map categoryInfoMap = new HashMap(); + + public void add(CategoryInfo categoryInfo) { + categoryInfoMap.put(categoryInfo.getCategoryName(), categoryInfo); + } + + public CategoryInfo get(String categoryName) { + return categoryInfoMap.get(categoryName); + } + + public void clear() { + categoryInfoMap.clear(); + } + + public Set getCategoryNames() { + return categoryInfoMap.keySet(); + } +} diff --git a/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/data/CategoryInfo.java b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/data/CategoryInfo.java new file mode 100644 index 0000000000..cc9b64735b --- /dev/null +++ b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/data/CategoryInfo.java @@ -0,0 +1,79 @@ +/** + * 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.archive.data; + +import java.util.List; + +import com.raytheon.uf.common.archive.config.DisplayData; + +/** + * This class used to maintain the state of a category so it can be restored + * when reselected. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 24, 2013 1966        rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ + +public class CategoryInfo { + /** Archive name for the category. */ + private final String archiveName; + + /** Category's name. */ + private final String categoryName; + + /** List of display items for the category. */ + private final List displayDataList; + + /** + * Contructor. + * + * @param archiveName + * @param categoryName + * @param displayInfoList + */ + public CategoryInfo(String archiveName, String categoryName, + List displayInfoList) { + this.archiveName = archiveName; + this.categoryName = categoryName; + this.displayDataList = displayInfoList; + } + + public String getArchiveName() { + return archiveName; + } + + public String getCategoryName() { + return categoryName; + } + + public List getDisplayDataList() { + return displayDataList; + } +} diff --git a/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/data/FileInfo.java b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/data/FileInfo.java index d656b96d90..de77c5c454 100644 --- a/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/data/FileInfo.java +++ b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/data/FileInfo.java @@ -33,7 +33,7 @@ import com.raytheon.uf.common.util.FileUtil; /** * This class uses a obtains information on a File in a Job in order to remove - * from the UI thread. + * from the UI thread. Use DirInfo instead. * *
  * 
@@ -48,7 +48,7 @@ import com.raytheon.uf.common.util.FileUtil;
  * @author rferrel
  * @version 1.0
  */
-
+@Deprecated
 public class FileInfo {
     private static final SizeJob sizeJob = new FileInfo.SizeJob();
 
@@ -103,7 +103,7 @@ public class FileInfo {
                 }
 
                 for (IUpdateListener listener : listeners) {
-                    listener.update(list);
+                    // listener.update(list);
                 }
             }
 
diff --git a/edexOsgi/com.raytheon.uf.common.archive/src/com/raytheon/uf/common/archive/IArchive.java b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/data/IArchiveTotals.java
similarity index 62%
rename from edexOsgi/com.raytheon.uf.common.archive/src/com/raytheon/uf/common/archive/IArchive.java
rename to cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/data/IArchiveTotals.java
index b356e3c23f..8cc6cfc6a8 100644
--- a/edexOsgi/com.raytheon.uf.common.archive/src/com/raytheon/uf/common/archive/IArchive.java
+++ b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/data/IArchiveTotals.java
@@ -17,12 +17,14 @@
  * See the AWIPS II Master Rights File ("Master Rights File.pdf") for
  * further licensing information.
  **/
-package com.raytheon.uf.common.archive;
+package com.raytheon.uf.viz.archive.data;
 
 import java.util.List;
 
+import com.raytheon.uf.common.archive.config.DisplayData;
+
 /**
- * Interface that defines a Archive.
+ * Interface for methods for getting totals needed by the ArchiveTableComp.
  * 
  * 
  * 
@@ -30,27 +32,17 @@ import java.util.List;
  * 
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
- * May 7, 2013  1966       bgonzale     Initial creation
+ * May 29, 2013 1996       rferrel     Initial creation
  * 
  * 
* - * @author bgonzale + * @author rferrel * @version 1.0 */ -public interface IArchive { - +public interface IArchiveTotals { /** - * Obtain a list archive elements that have expired. - * - * @param archiveName - * - Name of Archive Data. - * @param categoryNameList - * - List of categories to check. All categories are checked if - * the list is null or empty. - * @return archiveElementList + * Update total selected items and sizes. */ - List getExpiredElements(String archiveName, - List categoryNameList); - + public void updateTotals(List displayDatas); } diff --git a/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/data/IUpdateListener.java b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/data/IUpdateListener.java index f8c5cefff7..1916b3c928 100644 --- a/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/data/IUpdateListener.java +++ b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/data/IUpdateListener.java @@ -19,6 +19,8 @@ **/ package com.raytheon.uf.viz.archive.data; +import java.util.List; + /** * A listener to update file/directory information. * @@ -35,12 +37,11 @@ package com.raytheon.uf.viz.archive.data; * @author rferrel * @version 1.0 */ - public interface IUpdateListener { /** - * List of files/directories with updated information + * Table display state entries with updated information. * - * @param fileInfoArray + * @param dirInfos */ - public void update(FileInfo[] fileInfoArray); + public void update(List request); } diff --git a/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/data/SizeJob.java b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/data/SizeJob.java new file mode 100644 index 0000000000..3e4b249ead --- /dev/null +++ b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/data/SizeJob.java @@ -0,0 +1,206 @@ +package com.raytheon.uf.viz.archive.data; + +import java.io.File; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; +import java.util.concurrent.ConcurrentLinkedQueue; +import java.util.concurrent.atomic.AtomicBoolean; + +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 com.raytheon.uf.common.archive.config.ArchiveConfigManager; +import com.raytheon.uf.common.archive.config.DisplayData; +import com.raytheon.uf.common.util.FileUtil; + +/** + * Job to determine the size for a directory and its contents on a non-UI + * thread. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 13, 2013            rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ +public class SizeJob extends Job { + + /** The queue for requested sizes. */ + private final ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue(); + + /** + * Pending selected entries that still need to have the sizes determined. + */ + private final ConcurrentLinkedQueue selectedQueue = new ConcurrentLinkedQueue(); + + /** + * Indicates the job should stop computing the size of the current + * non-selected entry. + */ + private final AtomicBoolean stopComputeSize = new AtomicBoolean(false); + + /** + * The listeners to inform when job is done with an entry. + */ + private final List listeners = new ArrayList(); + + /** + * Constructor. + */ + public SizeJob() { + super("Size Job"); + setSystem(true); + } + + /** + * Add a Listener to inform when job has completed information on an entry. + * + * @param listener + */ + public void addUpdateListener(IUpdateListener listener) { + listeners.add(listener); + } + + /** + * Remove a listener. + * + * @param listener + */ + public void removeUpdateListener(IUpdateListener listener) { + listeners.remove(listener); + } + + /** + * Add entry to queue and if pending selected entries add them to the queue + * with same start/end times. + * + * @param fileInfo + */ + public void queue(SizeJobRequest fileInfo) { + queue.add(fileInfo); + + if (getState() == Job.NONE) { + schedule(); + } + } + + /** + * Clear queue but save selected entries still needing sizes. + */ + public void clearQueue() { + List pending = new ArrayList(); + + // Drain queue queue.removeAll() doesn't work. + while (!queue.isEmpty()) { + pending.add(queue.remove()); + } + + if (getState() != NONE) { + cancel(); + } + + // Save selected items that do not have sizes. + for (SizeJobRequest dirInfo : pending) { + DisplayData displayData = dirInfo.getDisplayData(); + + if (displayData.isSelected() && displayData.getSize() < 0L) { + if (!selectedQueue.contains(displayData)) { + selectedQueue.add(displayData); + } + } + } + } + + /** + * Requeue pending entries. + * + * @param startCal + * @param endCal + */ + public void requeueSelected(Calendar startCal, Calendar endCal) { + if (!selectedQueue.isEmpty()) { + DisplayData displayData = selectedQueue.remove(); + queue(new SizeJobRequest(displayData, startCal, endCal)); + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime. + * IProgressMonitor) + */ + @Override + protected IStatus run(IProgressMonitor monitor) { + if (monitor.isCanceled()) { + return Status.OK_STATUS; + } + + ArchiveConfigManager manager = ArchiveConfigManager.getInstance(); + + mainLoop: while (!queue.isEmpty()) { + SizeJobRequest dirInfo = queue.remove(); + + stopComputeSize.set(false); + DisplayData displayData = dirInfo.displayData; + Calendar startCal = dirInfo.startCal; + Calendar endCal = dirInfo.endCal; + + List files = manager.getDisplayFiles(displayData, startCal, + endCal); + + // Size no longer needed. + if (!displayData.isSelected() && stopComputeSize.get()) { + continue; + } + + dirInfo.files.clear(); + dirInfo.files.addAll(files); + long size = 0L; + for (File file : dirInfo.files) { + + // Skip when size no longer needed. + if (!displayData.isSelected() && stopComputeSize.get()) { + continue mainLoop; + } + + if (file.isDirectory()) { + size += FileUtil.sizeOfDirectory(file); + } else { + size += file.length(); + } + } + + displayData.setSize(size); + + List list = new ArrayList(1); + list.add(dirInfo); + for (IUpdateListener listener : listeners) { + listener.update(list); + } + } + + return Status.OK_STATUS; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.core.runtime.jobs.Job#canceling() + */ + @Override + protected void canceling() { + queue.clear(); + stopComputeSize.set(true); + } +} \ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/data/SizeJobRequest.java b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/data/SizeJobRequest.java new file mode 100644 index 0000000000..0de53cd1e8 --- /dev/null +++ b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/data/SizeJobRequest.java @@ -0,0 +1,82 @@ +/** + * 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.archive.data; + +import java.io.File; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; + +import com.raytheon.uf.common.archive.config.DisplayData; + +/** + * This class obtains information on a File in a Job in order to remove it from + * the UI thread. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 15, 2013 1966       rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ + +public class SizeJobRequest { + + /** Information from archive configuration manager. */ + final DisplayData displayData; + + /** Files or directories to obtain information on. */ + final List files = new ArrayList(); + + /** Start time inclusive. */ + final Calendar startCal; + + /** End time exclusive. */ + final Calendar endCal; + + /** + * Create and entry and place it on the queue. + * + * @param displayData + * @param startCal + * @param endCal + */ + public SizeJobRequest(DisplayData displayData, Calendar startCal, + Calendar endCal) { + this.displayData = displayData; + this.startCal = startCal; + this.endCal = endCal; + } + + /** + * + * @return displayData + */ + public DisplayData getDisplayData() { + return displayData; + } +} diff --git a/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/AbstractArchiveDlg.java b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/AbstractArchiveDlg.java new file mode 100644 index 0000000000..c9784a1dd8 --- /dev/null +++ b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/AbstractArchiveDlg.java @@ -0,0 +1,523 @@ +/** + * 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.archive.ui; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +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.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.graphics.Cursor; +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.Label; +import org.eclipse.swt.widgets.Shell; + +import com.raytheon.uf.common.archive.config.ArchiveConfig; +import com.raytheon.uf.common.archive.config.ArchiveConfigManager; +import com.raytheon.uf.common.archive.config.CategoryConfig; +import com.raytheon.uf.common.archive.config.DisplayData; +import com.raytheon.uf.common.util.SizeUtil; +import com.raytheon.uf.viz.archive.data.ArchiveInfo; +import com.raytheon.uf.viz.archive.data.CategoryInfo; +import com.raytheon.uf.viz.archive.data.IArchiveTotals; +import com.raytheon.uf.viz.archive.data.IUpdateListener; +import com.raytheon.uf.viz.archive.data.SizeJob; +import com.raytheon.uf.viz.archive.data.SizeJobRequest; +import com.raytheon.uf.viz.archive.ui.ArchiveTableComp.TableType; +import com.raytheon.uf.viz.core.VizApp; +import com.raytheon.viz.ui.dialogs.CaveSWTDialog; + +/** + * Abstract base class for Archive dialogs. Contains and manages information + * needed for the archive and category selectors and populates the selection + * table of display labels elements. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 30, 2013 1965       bgonzale     Initial creation
+ * Jun 10, 2013 1966       rferrel      Change to allow Case Creation to extend.
+ * 
+ * 
+ * + * @author bgonzale + * @version 1.0 + */ + +public abstract class AbstractArchiveDlg extends CaveSWTDialog implements + IArchiveTotals, IUpdateListener { + + /** Table composite that holds the table controls. */ + private ArchiveTableComp tableComp; + + /** Archive configuration combo box. */ + private Combo archCfgCbo; + + /** Category combo box. */ + private Combo categoryCbo; + + /** Information for populating the various table displays. */ + protected final Map archiveInfoMap = new HashMap(); + + /** + * Boolean to indicate when DisplayData is created should its selection be + * set based on the information in the configuration files. + */ + protected boolean setSelect = false; + + protected TableType tableType; + + protected final SizeJob sizeJob = new SizeJob(); + + /** + * @param parentShell + */ + public AbstractArchiveDlg(Shell parentShell) { + super(parentShell); + } + + /** + * @param parentShell + * @param swtStyle + */ + public AbstractArchiveDlg(Shell parentShell, int swtStyle) { + super(parentShell, swtStyle); + } + + /** + * @param parentShell + * @param style + * @param caveStyle + */ + public AbstractArchiveDlg(Shell parentShell, int style, int caveStyle) { + super(parentShell, style, caveStyle); + } + + public List getAllSelected() { + List allSelected = new ArrayList(); + for (String archiveName : archiveInfoMap.keySet()) { + ArchiveInfo archiveInfo = archiveInfoMap.get(archiveName); + for (String categoryName : archiveInfo.getCategoryNames()) { + CategoryInfo categoryInfo = archiveInfo.get(categoryName); + for (DisplayData displayData : categoryInfo + .getDisplayDataList()) { + if (displayData.isSelected()) { + allSelected.add(displayData); + } + } + } + } + return allSelected; + } + + /** + * @return the name of the currently selected archive in the dialog; null if + * none found + */ + public String getSelectedArchiveName() { + int archiveSelection = archCfgCbo.getSelectionIndex(); + String archiveName = archiveSelection == -1 ? null : archCfgCbo + .getItem(archiveSelection); + return archiveName; + } + + /** + * @return the name of the currently selected category in the dialog; null + * if none found + */ + public String getSelectedCategoryName() { + int categorySelection = categoryCbo.getSelectionIndex(); + String categoryName = categorySelection == -1 ? null : categoryCbo + .getItem(categorySelection); + return categoryName; + } + + /** + * @return the currently selected archive in the dialog; null if none found + */ + public ArchiveConfig getSelectedArchive() { + int archiveSelection = archCfgCbo.getSelectionIndex(); + String archiveName = archiveSelection == -1 ? null : archCfgCbo + .getItem(archiveSelection); + return ArchiveConfigManager.getInstance().getArchive(archiveName); + } + + /** + * @return the currently selected category in the dialog; null if none found + */ + public CategoryConfig getSelectedCategory() { + String archiveName = getSelectedArchiveName(); + ArchiveConfig archive = ArchiveConfigManager.getInstance().getArchive( + archiveName); + if (archive != null) { + String categoryName = getSelectedCategoryName(); + return archive.getCategory(categoryName); + } + return null; + } + + /** + * This method is called by the AbstractArchiveDlg to set the size text. + * + * @param prettyByteSize + */ + protected abstract void setTotalSizeText(String sizeStringText); + + protected abstract void setTotalSelectedItems(int totalSize); + + /** + * This method is called by the AbstractArchiveDlg to get the start of the + * time frame that bounds the data for the dialog. + * + * @return GMT Calendar + */ + protected abstract Calendar getStart(); + + /** + * This method is called by the AbstractArchiveDlg to get the end of the + * time frame that bounds the data for the dialog. + * + * @return GMT Calendar + */ + protected abstract Calendar getEnd(); + + /** + * Create the Archive and Category combo controls. + * + * @param comp + * Composite to put the controls in. + */ + protected Composite createComboControls(Composite comp) { + Composite comboComp = new Composite(comp, SWT.NONE); + GridLayout gl = new GridLayout(2, false); + GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); + comboComp.setLayout(gl); + comboComp.setLayoutData(gd); + + Label archCfgLbl = new Label(comboComp, SWT.NONE); + archCfgLbl.setText("Archive Config: "); + + gd = new GridData(200, SWT.DEFAULT); + archCfgCbo = new Combo(comboComp, SWT.VERTICAL | SWT.DROP_DOWN + | SWT.BORDER | SWT.READ_ONLY); + archCfgCbo.setLayoutData(gd); + archCfgCbo.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + archiveComboSelection(); + } + }); + + Label catLbl = new Label(comboComp, SWT.NONE); + catLbl.setText("Category: "); + + gd = new GridData(200, SWT.DEFAULT); + categoryCbo = new Combo(comboComp, SWT.VERTICAL | SWT.DROP_DOWN + | SWT.BORDER | SWT.READ_ONLY); + categoryCbo.setLayoutData(gd); + categoryCbo.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + categoryComboSelection(); + } + }); + + return comboComp; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.viz.ui.dialogs.CaveSWTDialog#preOpened() + */ + @Override + protected void preOpened() { + super.preOpened(); + setCursorBusy(true); + + // Setup to display blank dialog with busy cursor while getting data. + Job job = new Job("setup") { + @Override + protected IStatus run(IProgressMonitor monitor) { + initInfo(); + VizApp.runAsync(new Runnable() { + + @Override + public void run() { + populateComboBoxes(); + updateTableComp(); + } + }); + return Status.OK_STATUS; + } + }; + job.schedule(); + } + + /** + * Create the table control. + */ + protected void createTable() { + tableComp = new ArchiveTableComp(shell, tableType, this); + sizeJob.addUpdateListener(this); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.viz.ui.dialogs.CaveSWTDialogBase#disposed() + */ + @Override + protected void disposed() { + sizeJob.removeUpdateListener(this); + sizeJob.cancel(); + } + + /** + * Update table based on current item selections in archive and category. + */ + protected void updateTableComp() { + populateTableComp(); + } + + /** + * Initial population up of the combo boxes. + */ + private void populateComboBoxes() { + ArchiveConfigManager manager = ArchiveConfigManager.getInstance(); + boolean doSelect = false; + for (String archiveName : manager.getArchiveDataNamesList()) { + archCfgCbo.add(archiveName); + doSelect = true; + } + + if (doSelect) { + archCfgCbo.select(0); + archiveComboSelection(); + } + } + + /** + * Method invoked when archive combo selection is changed. + */ + protected void archiveComboSelection() { + populateCategoryCbo(); + } + + /** + * Populate the category combo based on the archive name and populate the + * table. + * + * @param archiveName + */ + private void populateCategoryCbo() { + String archiveName = getSelectedArchiveName(); + ArchiveConfigManager manager = ArchiveConfigManager.getInstance(); + categoryCbo.removeAll(); + for (String categoryName : manager.getCategoryNames(archiveName)) { + categoryCbo.add(categoryName); + } + categoryCbo.select(0); + categoryComboSelection(); + } + + /** + * Method invoked when the category combo selection is changed. + */ + protected void categoryComboSelection() { + populateTableComp(); + } + + /** + * Get information from manager for populating combo boxes and set up to get + * selected entries sizes. Intended for use on a non-UI thread. + */ + private void initInfo() { + ArchiveConfigManager manager = ArchiveConfigManager.getInstance(); + manager.reset(); + Calendar startCal = getStart(); + Calendar endCal = getEnd(); + String[] archiveNames = manager.getArchiveDataNamesList(); + for (String archiveName : archiveNames) { + ArchiveInfo archiveInfo = new ArchiveInfo(); + archiveInfoMap.put(archiveName, archiveInfo); + String[] categoryNames = manager.getCategoryNames(manager + .getArchive(archiveName)); + for (String categoryName : categoryNames) { + List displayDatas = manager.getDisplayData( + archiveName, categoryName, setSelect); + CategoryInfo categoryInfo = new CategoryInfo(archiveName, + categoryName, displayDatas); + archiveInfo.add(categoryInfo); + for (DisplayData displayData : displayDatas) { + if (displayData.isSelected()) { + sizeJob.queue(new SizeJobRequest(displayData, startCal, + endCal)); + } + } + } + } + } + + /** + * Populate the table based on the currently selected archive, category and + * adjust sizes on the display table. + */ + protected void populateTableComp() { + String archiveName = getSelectedArchiveName(); + String categoryName = getSelectedCategoryName(); + Calendar startCal = getStart(); + Calendar endCal = getEnd(); + + setCursorBusy(true); + sizeJob.clearQueue(); + + ArchiveInfo archiveInfo = archiveInfoMap.get(archiveName); + CategoryInfo categoryInfo = archiveInfo.get(categoryName); + + for (DisplayData displayData : categoryInfo.getDisplayDataList()) { + sizeJob.queue(new SizeJobRequest(displayData, startCal, endCal)); + } + sizeJob.requeueSelected(startCal, endCal); + + tableComp.populateTable(categoryInfo.getDisplayDataList()); + setCursorBusy(false); + } + + /** + * Set the shells cursor to the desire state. + * + * @param state + */ + protected void setCursorBusy(boolean state) { + Cursor cursor = null; + if (state) { + cursor = shell.getDisplay().getSystemCursor(SWT.CURSOR_WAIT); + } + shell.setCursor(cursor); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.archive.data.IArchiveTotals#updateTotals(java.util + * .List) + */ + @Override + public void updateTotals(List displayDatas) { + long totalSize = 0; + int totalSelected = 0; + + for (String archiveName : archiveInfoMap.keySet()) { + ArchiveInfo archiveInfo = archiveInfoMap.get(archiveName); + for (String categoryName : archiveInfo.getCategoryNames()) { + CategoryInfo categoryInfo = archiveInfo.get(categoryName); + for (DisplayData displayData : categoryInfo + .getDisplayDataList()) { + if (displayData.isSelected()) { + ++totalSelected; + if (totalSize != DisplayData.UNKNOWN_SIZE) { + long size = displayData.getSize(); + if (size >= 0) { + totalSize += size; + } else { + totalSize = DisplayData.UNKNOWN_SIZE; + } + } + } + } + } + } + + String sizeMsg = null; + if (totalSize == DisplayData.UNKNOWN_SIZE) { + sizeMsg = DisplayData.UNKNOWN_SIZE_LABEL; + } else { + sizeMsg = SizeUtil.prettyByteSize(totalSize); + } + + setTotalSizeText(sizeMsg); + setTotalSelectedItems(totalSelected); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.archive.data.IUpdateListener#update(java.util.List) + */ + @Override + public void update(List dirInfos) { + final List displayDatas = new ArrayList( + dirInfos.size()); + for (SizeJobRequest request : dirInfos) { + displayDatas.add(request.getDisplayData()); + } + + VizApp.runAsync(new Runnable() { + + @Override + public void run() { + tableComp.updateSize(displayDatas); + updateTotals(null); + } + }); + } + + /** + * Reset modification flag. + */ + protected void clearModified() { + tableComp.clearModified(); + } + + /** + * Add listener to inform when modification flag is set. + * + * @param iModifyListener + */ + protected void addModifiedListener(IModifyListener iModifyListener) { + tableComp.addModifiedListener(iModifyListener); + } + + /** + * Remove modification listener. + * + * @param iModifyListener + */ + protected void removeModifiedListener(IModifyListener iModifyListener) { + tableComp.removeModifiedListener(iModifyListener); + } +} diff --git a/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/ArchiveRetentionDlg.java b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/ArchiveRetentionDlg.java index 8d145ed743..4f4836f55a 100644 --- a/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/ArchiveRetentionDlg.java +++ b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/ArchiveRetentionDlg.java @@ -19,9 +19,14 @@ **/ package com.raytheon.uf.viz.archive.ui; +import java.util.Calendar; +import java.util.List; + import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.ShellAdapter; +import org.eclipse.swt.events.ShellEvent; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; @@ -29,11 +34,15 @@ import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Layout; +import org.eclipse.swt.widgets.MessageBox; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Spinner; +import com.raytheon.uf.common.archive.config.ArchiveConfigManager; +import com.raytheon.uf.common.archive.config.DisplayData; +import com.raytheon.uf.viz.archive.data.IArchiveTotals; import com.raytheon.uf.viz.archive.ui.ArchiveTableComp.TableType; -import com.raytheon.viz.ui.dialogs.CaveSWTDialog; +import com.raytheon.uf.viz.core.VizApp; /** * Archive retention dialog. @@ -45,22 +54,34 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * May 23, 2013 #1964 lvenable Initial creation + * May 31, 2013 #1965 bgonzale Initial work for updating retention configurations. + * Jun 10, 2013 #1966 rferrel Implemented hooks to get display and save to work. * *
* * @author lvenable * @version 1.0 */ -public class ArchiveRetentionDlg extends CaveSWTDialog { +public class ArchiveRetentionDlg extends AbstractArchiveDlg implements + IArchiveTotals, IModifyListener { - /** Table composite that holds the table controls. */ - private ArchiveTableComp tableComp; + /** Current Archive/Category selection's minimum retention hours. */ + private RetentionHours minRetention; - /** Archive config combo box. */ - private Combo archCfgCbo; + /** Current Archive/Category selection's extended retention hours. */ + private RetentionHours extRetention; - /** Category combo box. */ - private Combo categoryCbo; + /** Displays the total number of selected items for all tables. */ + private Label totalSelectedItems; + + /** Displays the total size of selected items. */ + private Label totalSizeLbl; + + /** Performs save action button. */ + private Button saveBtn; + + /** Flag set when user wants to close with unsaved modifications. */ + boolean closeFlag = false; /** * Constructor. @@ -71,18 +92,31 @@ public class ArchiveRetentionDlg extends CaveSWTDialog { public ArchiveRetentionDlg(Shell parentShell) { super(parentShell, SWT.DIALOG_TRIM | SWT.MIN, CAVE.DO_NOT_BLOCK | CAVE.MODE_INDEPENDENT | CAVE.INDEPENDENT_SHELL); + this.setSelect = true; + this.tableType = TableType.Retention; } + /* + * (non-Javadoc) + * + * @see com.raytheon.viz.ui.dialogs.CaveSWTDialogBase#constructShellLayout() + */ @Override protected Layout constructShellLayout() { // Create the main layout for the shell. GridLayout mainLayout = new GridLayout(1, false); mainLayout.marginHeight = 2; mainLayout.marginWidth = 2; - return mainLayout; } + /* + * (non-Javadoc) + * + * @see + * com.raytheon.viz.ui.dialogs.CaveSWTDialogBase#initializeComponents(org + * .eclipse.swt.widgets.Shell) + */ @Override protected void initializeComponents(Shell shell) { setText("Archive Retention"); @@ -92,6 +126,7 @@ public class ArchiveRetentionDlg extends CaveSWTDialog { gl.marginWidth = 0; gl.horizontalSpacing = 0; mainComp.setLayout(gl); + ArchiveConfigManager.getInstance().reset(); init(); } @@ -101,12 +136,8 @@ public class ArchiveRetentionDlg extends CaveSWTDialog { */ private void init() { createRetentionControls(); - createTable(); - addSeparator(shell, SWT.HORIZONTAL); + GuiUtil.addSeparator(shell, SWT.HORIZONTAL); createBottomActionButtons(); - - // TODO : Remove this when functionality is implemented - populateComboBoxes(); } /** @@ -114,7 +145,7 @@ public class ArchiveRetentionDlg extends CaveSWTDialog { */ private void createRetentionControls() { Composite retentionComp = new Composite(shell, SWT.NONE); - GridLayout gl = new GridLayout(5, false); + GridLayout gl = new GridLayout(2, false); GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); retentionComp.setLayout(gl); retentionComp.setLayoutData(gd); @@ -122,103 +153,71 @@ public class ArchiveRetentionDlg extends CaveSWTDialog { /* * Top row of controls. */ - Label archCfgLbl = new Label(retentionComp, SWT.NONE); - archCfgLbl.setText("Archive Config: "); + createComboControls(retentionComp); + createTable(); - gd = new GridData(200, SWT.DEFAULT); - archCfgCbo = new Combo(retentionComp, SWT.VERTICAL | SWT.DROP_DOWN - | SWT.BORDER | SWT.READ_ONLY); - archCfgCbo.setLayoutData(gd); - archCfgCbo.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - /* - * TODO - add code to update the category combo box - */ - } - }); + // composite for retention time selection + Composite selectionComp = new Composite(retentionComp, SWT.NONE); + selectionComp.setLayout(new GridLayout(3, true)); + selectionComp.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, + false)); gd = new GridData(); gd.horizontalIndent = 20; - Label minRetentionLbl = new Label(retentionComp, SWT.NONE); + Label minRetentionLbl = new Label(selectionComp, SWT.NONE); minRetentionLbl.setText("Minimum Retention: "); minRetentionLbl.setLayoutData(gd); gd = new GridData(60, SWT.DEFAULT); - final Spinner minRetentionSpnr = new Spinner(retentionComp, SWT.BORDER); + Spinner minRetentionSpnr = new Spinner(selectionComp, SWT.BORDER); minRetentionSpnr.setIncrement(1); minRetentionSpnr.setPageIncrement(5); minRetentionSpnr.setMaximum(Integer.MAX_VALUE); minRetentionSpnr.setMinimum(1); minRetentionSpnr.setLayoutData(gd); - final Combo minRetentionCbo = new Combo(retentionComp, SWT.VERTICAL + Combo minRetentionCbo = new Combo(selectionComp, SWT.VERTICAL | SWT.DROP_DOWN | SWT.BORDER | SWT.READ_ONLY); - minRetentionCbo.addSelectionListener(new SelectionAdapter() { + minRetention = new RetentionHours(1, minRetentionSpnr, minRetentionCbo) { + @Override - public void widgetSelected(SelectionEvent e) { - handleRetentionSelection(minRetentionCbo, minRetentionSpnr); + protected boolean handleTimeSelection() { + boolean state = super.handleTimeSelection(); + getSelectedArchive().setRetentionHours(getHours()); + return state; } - }); - minRetentionCbo.add("Hours"); - minRetentionCbo.add("Days"); - minRetentionCbo.select(0); - minRetentionCbo.setData(minRetentionCbo.getItem(minRetentionCbo - .getSelectionIndex())); + }; + minRetention.addModifyListener(this); /* * Bottom row of controls. */ - Label catLbl = new Label(retentionComp, SWT.NONE); - catLbl.setText("Category: "); - - gd = new GridData(200, SWT.DEFAULT); - categoryCbo = new Combo(retentionComp, SWT.VERTICAL | SWT.DROP_DOWN - | SWT.BORDER | SWT.READ_ONLY); - categoryCbo.setLayoutData(gd); - categoryCbo.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - /* - * TODO - add code to update the information in the table - */ - } - }); - gd = new GridData(); gd.horizontalIndent = 20; - Label extRetentionLbl = new Label(retentionComp, SWT.NONE); + Label extRetentionLbl = new Label(selectionComp, SWT.NONE); extRetentionLbl.setText("Extended Retention: "); extRetentionLbl.setLayoutData(gd); gd = new GridData(60, SWT.DEFAULT); - final Spinner extRetentionSpnr = new Spinner(retentionComp, SWT.BORDER); + Spinner extRetentionSpnr = new Spinner(selectionComp, SWT.BORDER); extRetentionSpnr.setIncrement(1); extRetentionSpnr.setPageIncrement(5); extRetentionSpnr.setMaximum(Integer.MAX_VALUE); - extRetentionSpnr.setMinimum(1); + extRetentionSpnr.setMinimum(0); extRetentionSpnr.setLayoutData(gd); - final Combo extRetentionCbo = new Combo(retentionComp, SWT.VERTICAL + Combo extRetentionCbo = new Combo(selectionComp, SWT.VERTICAL | SWT.DROP_DOWN | SWT.BORDER | SWT.READ_ONLY); - extRetentionCbo.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - handleRetentionSelection(extRetentionCbo, extRetentionSpnr); - } - }); - extRetentionCbo.add("Hours"); - extRetentionCbo.add("Days"); - extRetentionCbo.select(0); - extRetentionCbo.setData(extRetentionCbo.getItem(extRetentionCbo - .getSelectionIndex())); - } + extRetention = new RetentionHours(1, extRetentionSpnr, extRetentionCbo) { - /** - * Create the table control. - */ - private void createTable() { - tableComp = new ArchiveTableComp(shell, TableType.Case); + @Override + protected boolean handleTimeSelection() { + boolean state = super.handleTimeSelection(); + getSelectedCategory().setRetentionHours(getHours()); + return state; + } + }; + extRetention.addModifyListener(this); } /** @@ -227,28 +226,36 @@ public class ArchiveRetentionDlg extends CaveSWTDialog { private void createBottomActionButtons() { Composite actionControlComp = new Composite(shell, SWT.NONE); - GridLayout gl = new GridLayout(3, false); + GridLayout gl = new GridLayout(2, false); GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); actionControlComp.setLayout(gl); actionControlComp.setLayoutData(gd); - Button calcSizeBtn = new Button(actionControlComp, SWT.PUSH); - calcSizeBtn.setText(" Calculate Sizes "); - calcSizeBtn.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - // TODO : add calculate size functionality - } - }); + // TODO - For the future ? + // Button calcSizeBtn = new Button(actionControlComp, SWT.PUSH); + // calcSizeBtn.setText(" Calculate Sizes "); + // calcSizeBtn.addSelectionListener(new SelectionAdapter() { + // @Override + // public void widgetSelected(SelectionEvent e) { + // // TODO : add calculate size functionality + // // With Roger's automated size calculation code, this doesn't + // // seem relevant unless it is for calculating compressed size + // } + // }); - Button saveBtn = new Button(actionControlComp, SWT.PUSH); - saveBtn.setText(" Save... "); + saveBtn = new Button(actionControlComp, SWT.PUSH); + saveBtn.setText(" Save "); saveBtn.addSelectionListener(new SelectionAdapter() { @Override - public void widgetSelected(SelectionEvent e) { - // TODO : add save functionality + public void widgetSelected(SelectionEvent selectionEvent) { + ArchiveConfigManager manager = ArchiveConfigManager + .getInstance(); + manager.save(); + saveBtn.setEnabled(false); + clearModified(); } }); + saveBtn.setEnabled(false); gd = new GridData(SWT.RIGHT, SWT.DEFAULT, true, false); Button closeBtn = new Button(actionControlComp, SWT.PUSH); @@ -257,93 +264,198 @@ public class ArchiveRetentionDlg extends CaveSWTDialog { closeBtn.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { - close(); + if (verifyClose()) { + close(); + } else { + e.doit = false; + } } }); } /** - * Handle the retention selection for both minimum and extended retention. + * When unsaved modifications this asks the user to verify the close. * - * @param comboBox - * Retention combo box. - * @param spinner - * Retention spinner. + * @return true when okay to close. */ - private void handleRetentionSelection(Combo comboBox, Spinner spinner) { - // If the selection didn't change then just return. - if (comboBox.getItem(comboBox.getSelectionIndex()).equals( - (String) comboBox.getData())) { - return; + private boolean verifyClose() { + boolean state = true; + if (isModified()) { + MessageBox box = new MessageBox(shell, SWT.ICON_WARNING | SWT.OK + | SWT.CANCEL); + box.setText("Close Retention"); + box.setMessage("Unsave changes.\nSelect OK to continue."); + state = box.open() == SWT.OK; } + closeFlag = state; + return state; + } - int time = 0; - - if (comboBox.getItem(comboBox.getSelectionIndex()).equals("Hours")) { - time = convertTime(true, spinner.getSelection()); - } else { - time = convertTime(false, spinner.getSelection()); + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.archive.ui.AbstractArchiveDlg#setTotalSizeText(java + * .lang.String) + */ + @Override + protected void setTotalSizeText(String sizeStringText) { + if (totalSizeLbl != null && !totalSizeLbl.isDisposed()) { + totalSizeLbl.setText(sizeStringText); } + } - spinner.setSelection(time); - comboBox.setData(comboBox.getItem(comboBox.getSelectionIndex())); + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.archive.ui.AbstractArchiveDlg#setTotalSelectedItems + * (int) + */ + @Override + protected void setTotalSelectedItems(int totalSize) { + if (totalSelectedItems != null && !totalSelectedItems.isDisposed()) { + totalSelectedItems.setText("" + totalSize); + } + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.archive.ui.AbstractArchiveDlg#getStart() + */ + @Override + protected Calendar getStart() { + // display all elements so no start bound + return null; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.archive.ui.AbstractArchiveDlg#getEnd() + */ + @Override + protected Calendar getEnd() { + // display all elements so no end bound + return null; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.archive.ui.AbstractArchiveDlg#updateTotals(java.util + * .List) + */ + @Override + public void updateTotals(List displayDatas) { + super.updateTotals(displayDatas); + if (displayDatas != null) { + for (DisplayData displayData : displayDatas) { + displayData.updateCategory(); + } + } + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.archive.ui.AbstractArchiveDlg#archiveComboSelection() + */ + @Override + protected void archiveComboSelection() { + super.archiveComboSelection(); + minRetention.setHours(getSelectedArchive().getRetentionHours()); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.uf.viz.archive.ui.AbstractArchiveDlg#categoryComboSelection + * () + */ + @Override + protected void categoryComboSelection() { + super.categoryComboSelection(); + extRetention.setHours(getSelectedCategory().getRetentionHours()); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.archive.ui.IModifyListener#modified() + */ + @Override + public void modified() { + saveBtn.setEnabled(true); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.archive.ui.AbstractArchiveDlg#clearModified() + */ + @Override + public void clearModified() { + super.clearModified(); + minRetention.clearModified(); + extRetention.clearModified(); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.archive.ui.AbstractArchiveDlg#preOpened() + */ + @Override + protected void preOpened() { + super.preOpened(); + addModifiedListener(this); + shell.addShellListener(new ShellAdapter() { + + @Override + public void shellClosed(ShellEvent e) { + if (closeFlag || !isModified()) { + return; + } + + e.doit = false; + VizApp.runAsync(new Runnable() { + + @Override + public void run() { + if (verifyClose()) { + close(); + } + } + }); + } + }); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.archive.ui.AbstractArchiveDlg#disposed() + */ + @Override + protected void disposed() { + minRetention.removeModifyListener(this); + extRetention.removeModifyListener(this); + removeModifiedListener(this); + super.disposed(); } /** - * Covert time from either hours to days or days to hours. + * Indicate unsaved user changes. * - * @param daysToHours - * Flag indicating how to convert the time. - * @param time - * Time to be converted. - * @return The converted time. + * @return modified */ - private int convertTime(boolean daysToHours, int time) { - int convertedTime = 0; - - if (daysToHours) { - convertedTime = time * 24; - } else { - convertedTime = time / 24; - } - - return convertedTime; - } - - /** - * Add a separator line to the provided container. - * - * @param container - * Composite. - * @param orientation - * Vertical or horizontal orientation. - */ - private void addSeparator(Composite container, int orientation) { - // Separator label - GridData gd; - - if (orientation == SWT.HORIZONTAL) { - gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); - } else { - gd = new GridData(SWT.DEFAULT, SWT.FILL, false, true); - } - - Label sepLbl = new Label(container, SWT.SEPARATOR | orientation); - sepLbl.setLayoutData(gd); - } - - /******************************************************** - * TEST METHODS - to be removed when functionality is implemented. - * ****************************************************** - */ - private void populateComboBoxes() { - archCfgCbo.add("Raw"); - archCfgCbo.add("Processed"); - archCfgCbo.select(0); - - categoryCbo.add("Radar"); - categoryCbo.add("Point"); - categoryCbo.add("Satellite"); - categoryCbo.select(0); + private boolean isModified() { + return (saveBtn != null) && !saveBtn.isDisposed() + && saveBtn.isEnabled(); } } diff --git a/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/ArchiveTableComp.java b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/ArchiveTableComp.java index 4e72f90b67..8923e72b3f 100644 --- a/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/ArchiveTableComp.java +++ b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/ArchiveTableComp.java @@ -19,6 +19,11 @@ **/ package com.raytheon.uf.viz.archive.ui; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +import org.apache.commons.lang.ArrayUtils; import org.eclipse.swt.SWT; import org.eclipse.swt.events.MouseAdapter; import org.eclipse.swt.events.MouseEvent; @@ -28,13 +33,19 @@ import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; 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 com.raytheon.uf.common.archive.config.DisplayData; +import com.raytheon.uf.common.util.SizeUtil; +import com.raytheon.uf.viz.archive.data.IArchiveTotals; + /** * Archive table composite that contains the SWT table. * @@ -53,6 +64,12 @@ import org.eclipse.swt.widgets.TableItem; */ public class ArchiveTableComp extends Composite { + /** Column to display label information. */ + private final int LABEL_COL_INDEX = 0; + + /** Column to display size information,. */ + private final int SIZE_COL_INDEX = 1; + /** Table control. */ private Table table; @@ -71,7 +88,23 @@ public class ArchiveTableComp extends Composite { }; /** Current table type. */ - private TableType tableType = TableType.Retention; + private final TableType type; + + /** Allows the parent dialog log to update other total displays. */ + private final IArchiveTotals iArchiveTotals; + + /** Data for the currently display table */ + private DisplayData[] tableData; + + /** + * Modification state set to true only when user performs a modification. + */ + private boolean modifiedState = false; + + /** + * Listeners to inform when user changes the modification state. + */ + private final List modifiedListeners = new CopyOnWriteArrayList(); /** * Constructor. @@ -81,10 +114,12 @@ public class ArchiveTableComp extends Composite { * @param type * Table type. */ - public ArchiveTableComp(Composite parent, TableType type) { + public ArchiveTableComp(Composite parent, TableType type, + IArchiveTotals iTotalSelectedSize) { super(parent, 0); - tableType = type; + this.type = type; + this.iArchiveTotals = iTotalSelectedSize; init(); } @@ -101,43 +136,50 @@ public class ArchiveTableComp extends Composite { this.setLayoutData(gd); createTable(); - createTableLabels(); - updateSelectionLabel(); + if (type != TableType.Retention) { + createTableLabels(); + } } /** * Create the table control. */ private void createTable() { + GridData gd = null; + table = new Table(this, SWT.CHECK | SWT.BORDER | SWT.V_SCROLL - | SWT.H_SCROLL | SWT.MULTI); - GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, true); + | SWT.H_SCROLL | SWT.MULTI | SWT.VIRTUAL); + gd = new GridData(SWT.FILL, SWT.DEFAULT, true, true); gd.widthHint = 730; gd.heightHint = 270; table.setLayoutData(gd); table.setHeaderVisible(true); table.setLinesVisible(true); + table.addListener(SWT.SetData, new Listener() { - TableColumn pathColumn = new TableColumn(table, SWT.CENTER); - pathColumn.setText("Path"); + @Override + public void handleEvent(Event event) { + TableItem item = (TableItem) event.item; + int index = table.indexOf(item); + DisplayData displayData = tableData[index]; + item.setText(new String[] { displayData.getDisplayLabel(), + displayData.getSizeLabel() }); + item.setChecked(displayData.isSelected()); + } + }); + + TableColumn pathColumn = new TableColumn(table, SWT.LEFT); + pathColumn.setText("Label"); TableColumn sizeColumn = new TableColumn(table, SWT.CENTER); - if (tableType == TableType.Retention) { - sizeColumn.setText("Current Size (MB)"); - } else if (tableType == TableType.Case) { - sizeColumn.setText("Size (MB)"); + if (type == TableType.Retention) { + sizeColumn.setText("Current Size"); + } else if (type == TableType.Case) { + sizeColumn.setText("Size"); } - populateTable(); - - for (int i = 0; i < 2; i++) { - table.getColumn(i).setResizable(false); - table.getColumn(i).setMoveable(false); - table.getColumn(i).pack(); - } - - table.getColumn(1).setWidth(100); + table.getColumn(0).setWidth(500); table.addMouseListener(new MouseAdapter() { @Override @@ -152,9 +194,23 @@ public class ArchiveTableComp extends Composite { table.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { - updateSelectionLabel(); + if (e.detail == SWT.CHECK) { + updateSelectionLabels(); + setModified(); + } } }); + + Listener sortListener = new Listener() { + + @Override + public void handleEvent(Event event) { + sortColumn(event); + } + }; + + pathColumn.addListener(SWT.Selection, sortListener); + sizeColumn.addListener(SWT.Selection, sortListener); } /** @@ -171,30 +227,89 @@ public class ArchiveTableComp extends Composite { selectedLbl = new Label(lblComp, SWT.NONE); selectedLbl.setLayoutData(gd); - /* - * TODO : keep for future use. This will be used to show the total size - * of the selected items in the table. - */ - // gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); - // sizeLbl = new Label(lblComp, SWT.NONE); - // sizeLbl.setLayoutData(gd); - // sizeLbl.setText("Size of Selected items: 0" + sizeSuffix); + gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); + sizeLbl = new Label(lblComp, SWT.NONE); + sizeLbl.setLayoutData(gd); } /** - * Update the selection items label. + * Sort table roles by desired column and direction. + * + * @param e */ - private void updateSelectionLabel() { - TableItem[] itemArray = table.getItems(); - int count = 0; + private void sortColumn(Event e) { + TableColumn sortColumn = table.getSortColumn(); + TableColumn eventColumn = (TableColumn) e.widget; - for (TableItem ti : itemArray) { - if (ti.getChecked()) { - count++; - } + int sortDir = table.getSortDirection(); + int index = eventColumn == table.getColumn(LABEL_COL_INDEX) ? LABEL_COL_INDEX + : SIZE_COL_INDEX; + + if (sortColumn == eventColumn) { + sortDir = ((sortDir == SWT.UP) ? SWT.DOWN : SWT.UP); + } else { + table.setSortColumn(eventColumn); + sortDir = SWT.UP; } - selectedLbl.setText("Selected Items: " + count); + switch (index) { + case LABEL_COL_INDEX: + Arrays.sort(tableData, DisplayData.LABEL_ORDER); + if (sortDir == SWT.DOWN) { + ArrayUtils.reverse(tableData); + } + break; + case SIZE_COL_INDEX: + Arrays.sort(tableData, DisplayData.SIZE_ORDER); + if (sortDir == SWT.DOWN) { + ArrayUtils.reverse(tableData); + } + break; + default: + // Programmer error should never get here. + throw new IndexOutOfBoundsException("Unknown column index."); + } + table.setSortDirection(sortDir); + table.clearAll(); + } + + /** + * Update the selection items labels. + */ + private void updateSelectionLabels() { + int count = 0; + long tableTotalSize = 0; + + for (int index = 0; index < tableData.length; ++index) { + DisplayData displayData = tableData[index]; + TableItem item = table.getItem(index); + if (item.getChecked()) { + ++count; + displayData.setSelected(true); + if (tableTotalSize >= 0) { + long diSize = displayData.getSize(); + if (diSize < 0) { + tableTotalSize = diSize; + } else { + tableTotalSize += diSize; + } + } + } else { + displayData.setSelected(false); + } + } + List displayDatas = Arrays.asList(tableData); + + if (selectedLbl != null) { + selectedLbl.setText("Table Selected Items: " + count); + + String sizeString = DisplayData.UNKNOWN_SIZE_LABEL; + if (tableTotalSize >= 0) { + sizeString = SizeUtil.prettyByteSize(tableTotalSize); + } + sizeLbl.setText("Table Selected Size: " + sizeString); + } + iArchiveTotals.updateTotals(displayDatas); } /** @@ -260,12 +375,11 @@ public class ArchiveTableComp extends Composite { */ private void handleCheckSelectedRow(boolean check) { TableItem[] itemArray = table.getSelection(); - for (TableItem ti : itemArray) { ti.setChecked(check); } - updateSelectionLabel(); + updateSelectionLabels(); } /** @@ -280,24 +394,86 @@ public class ArchiveTableComp extends Composite { for (TableItem ti : itemArray) { ti.setChecked(check); } + setModified(); - updateSelectionLabel(); + updateSelectionLabels(); + } + + /** + * Check the current table to see if the size of any entries needs to be + * updated. + * + * @param displayDatas + */ + public void updateSize(List displayDatas) { + if (tableData != null && tableData.length > 0) { + for (DisplayData displayData : displayDatas) { + for (int index = 0; index < tableData.length; ++index) { + if (displayData.equals(tableData[index])) { + table.getItem(index) + .setText(displayData.getSizeLabel()); + table.clear(index); + } + } + } + updateSelectionLabels(); + } + } + + /** + * Set up table with values in the list. + * + * @param displayDatas + */ + protected void populateTable(List displayDatas) { + tableData = displayDatas.toArray(new DisplayData[0]); + table.removeAll(); + table.setItemCount(tableData.length); + + for (int i = 0; i < 2; i++) { + table.getColumn(i).setResizable(false); + table.getColumn(i).setMoveable(false); + table.getColumn(i).pack(); + } + table.getColumn(0).setWidth(600); + table.setSortColumn(table.getColumn(LABEL_COL_INDEX)); + table.setSortDirection(SWT.UP); + table.clearAll(); + } + + /** + * Check the modified state and inform listeners when it changes. + */ + private void setModified() { + if (!modifiedState) { + modifiedState = true; + for (IModifyListener iModifyListener : modifiedListeners) { + iModifyListener.modified(); + } + } + } + + /** + * Reset the modified state. + */ + public void clearModified() { + modifiedState = false; + } + + /** + * Add listener that wants to be informed when the modified state is + * changed. + * + * @param iModifyListener + */ + public void addModifiedListener(IModifyListener iModifyListener) { + modifiedListeners.add(iModifyListener); } /* - * TODO : this is just for display purposes. This will go away when the - * functionality is implemented. + * Remove the listener. */ - private void populateTable() { - for (int i = 0; i < 150; i++) { - TableItem item = new TableItem(table, SWT.NONE); - item.setText(0, - "/home/lvenable/caveData/configuration/base/com.raytheon.uf.viz.gisdatastore/" - + i + " "); - if (i % 5 == 0) { - item.setChecked(true); - } - item.setText(1, "?????"); - } + public void removeModifiedListener(IModifyListener iModifyListener) { + modifiedListeners.remove(iModifyListener); } } diff --git a/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/CaseCreationDlg.java b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/CaseCreationDlg.java index f0dc0c0cf8..eb39bdc72c 100644 --- a/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/CaseCreationDlg.java +++ b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/CaseCreationDlg.java @@ -19,12 +19,20 @@ **/ package com.raytheon.uf.viz.archive.ui; +import java.io.File; import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; import java.util.Date; +import java.util.List; +import org.eclipse.core.runtime.jobs.IJobChangeEvent; +import org.eclipse.core.runtime.jobs.JobChangeAdapter; +import org.eclipse.jface.dialogs.MessageDialog; 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.GC; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.layout.GridData; @@ -33,16 +41,26 @@ import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.DirectoryDialog; +import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Layout; import org.eclipse.swt.widgets.MessageBox; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Spinner; +import com.raytheon.uf.common.archive.config.ArchiveConfigManager; +import com.raytheon.uf.common.archive.config.DisplayData; import com.raytheon.uf.common.time.util.TimeUtil; +import com.raytheon.uf.common.util.SizeUtil; +import com.raytheon.uf.viz.archive.data.ArchiveInfo; +import com.raytheon.uf.viz.archive.data.CategoryInfo; +import com.raytheon.uf.viz.archive.data.IArchiveTotals; +import com.raytheon.uf.viz.archive.data.IUpdateListener; +import com.raytheon.uf.viz.archive.data.SizeJobRequest; import com.raytheon.uf.viz.archive.ui.ArchiveTableComp.TableType; +import com.raytheon.uf.viz.core.VizApp; import com.raytheon.viz.ui.dialogs.AwipsCalendar; -import com.raytheon.viz.ui.dialogs.CaveSWTDialog; +import com.raytheon.viz.ui.dialogs.ICloseCallback; /** * @@ -54,17 +72,17 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog; * * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * May 23, 2013 #1964 lvenable Initial creation + * May 23, 2013 #1964 lvenable Initial creation + * Jun 10, 2013 #1966 rferrel Implemented back in hooks for display + * and generation of cases. * * * * @author lvenable * @version 1.0 */ -public class CaseCreationDlg extends CaveSWTDialog { - - /** Table control */ - private ArchiveTableComp tableComp; +public class CaseCreationDlg extends AbstractArchiveDlg implements + IArchiveTotals, IUpdateListener { /** Start time label. */ private Label startTimeLbl; @@ -78,11 +96,11 @@ public class CaseCreationDlg extends CaveSWTDialog { /** End date. */ private Date endDate; - /** Archive configuration combo box. */ - private Combo archCfgCbo; + /** Action to bring up the case name dialog. */ + private Button caseNameCreate; - /** Category combo box. */ - private Combo categoryCbo; + /** Display the case name. */ + private Label caseNameLbl; /** Compression check box. */ private Button compressChk; @@ -102,13 +120,28 @@ public class CaseCreationDlg extends CaveSWTDialog { /** Directory location label. */ private Label locationLbl; + /** Directory location state. */ + private Label locationStateLbl; + /** Uncompressed file size label. */ private Label uncompressSizeLbl; + /** Displays total number of items selected from all categories. */ + private Label totalSelectedItemsLbl; + + /** Button to generate the case. */ + private Button generateBtn; + /** Date format. */ private SimpleDateFormat dateFmt = new SimpleDateFormat( "E MMM dd yyyy HH:00 z"); + /** Archive configuration manager */ + private ArchiveConfigManager manager = ArchiveConfigManager.getInstance(); + + /** Number of selected items. */ + private int selectedItemsSize = 0; + /** * Constructor. * @@ -118,8 +151,15 @@ public class CaseCreationDlg extends CaveSWTDialog { public CaseCreationDlg(Shell parentShell) { super(parentShell, SWT.DIALOG_TRIM | SWT.MIN, CAVE.DO_NOT_BLOCK | CAVE.MODE_INDEPENDENT | CAVE.INDEPENDENT_SHELL); + this.setSelect = false; + this.tableType = TableType.Case; } + /* + * (non-Javadoc) + * + * @see com.raytheon.viz.ui.dialogs.CaveSWTDialogBase#constructShellLayout() + */ @Override protected Layout constructShellLayout() { // Create the main layout for the shell. @@ -130,9 +170,16 @@ public class CaseCreationDlg extends CaveSWTDialog { return mainLayout; } + /* + * (non-Javadoc) + * + * @see + * com.raytheon.viz.ui.dialogs.CaveSWTDialogBase#initializeComponents(org + * .eclipse.swt.widgets.Shell) + */ @Override protected void initializeComponents(Shell shell) { - setText("Case Creation"); + setText("Archive Case Creation"); Composite mainComp = new Composite(shell, SWT.NONE); GridLayout gl = new GridLayout(1, false); gl.marginHeight = 0; @@ -140,6 +187,8 @@ public class CaseCreationDlg extends CaveSWTDialog { gl.horizontalSpacing = 0; mainComp.setLayout(gl); + manager.reset(); + init(); } @@ -147,17 +196,14 @@ public class CaseCreationDlg extends CaveSWTDialog { * Initialize method to create all of the composite & controls. */ private void init() { - createTimeControls(); - addSeparator(shell, SWT.HORIZONTAL); + GuiUtil.addSeparator(shell, SWT.HORIZONTAL); createCaseCompressionControls(); - addSeparator(shell, SWT.HORIZONTAL); + GuiUtil.addSeparator(shell, SWT.HORIZONTAL); createFileBrowserControls(); createTable(); - addSeparator(shell, SWT.HORIZONTAL); + GuiUtil.addSeparator(shell, SWT.HORIZONTAL); createBottomActionButtons(); - - populateComboBoxes(); } /** @@ -199,9 +245,10 @@ public class CaseCreationDlg extends CaveSWTDialog { endTimeLbl = new Label(timeComp, SWT.BORDER); endTimeLbl.setLayoutData(gd); - Date date = TimeUtil.newDate(); - startDate = date; - endDate = date; + endDate = TimeUtil.newDate(); + long time = endDate.getTime(); + time -= TimeUtil.MILLIS_PER_DAY; + startDate = new Date(time); startTimeLbl.setText(dateFmt.format(startDate)); endTimeLbl.setText(dateFmt.format(endDate)); } @@ -217,54 +264,35 @@ public class CaseCreationDlg extends CaveSWTDialog { caseCompressionComp.setLayoutData(gd); createComboControls(caseCompressionComp); - addSeparator(caseCompressionComp, SWT.VERTICAL); + GuiUtil.addSeparator(caseCompressionComp, SWT.VERTICAL); createCompressionControls(caseCompressionComp); } - /** - * Create the Archive and Category combo controls. + /* + * (non-Javadoc) * - * @param comp - * Composite to put the controls in. + * @see + * com.raytheon.uf.viz.archive.ui.AbstractArchiveDlg#createComboControls + * (org.eclipse.swt.widgets.Composite) */ - private void createComboControls(Composite comp) { - Composite comboComp = new Composite(comp, SWT.NONE); - GridLayout gl = new GridLayout(2, false); - GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); - comboComp.setLayout(gl); - comboComp.setLayoutData(gd); + protected Composite createComboControls(Composite comp) { + Composite comboComp = super.createComboControls(comp); - Label archCfgLbl = new Label(comboComp, SWT.NONE); - archCfgLbl.setText("Archive Config: "); + caseNameCreate = new Button(comboComp, SWT.PUSH); + caseNameCreate.setText(" Case Name... "); + caseNameCreate.addSelectionListener(new SelectionAdapter() { - gd = new GridData(200, SWT.DEFAULT); - archCfgCbo = new Combo(comboComp, SWT.VERTICAL | SWT.DROP_DOWN - | SWT.BORDER | SWT.READ_ONLY); - archCfgCbo.setLayoutData(gd); - archCfgCbo.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { - /* - * TODO - add code to update the category combo box - */ + handleCaseNameSelection(); } }); + caseNameCreate.setToolTipText("Must first select \"Case Location\"."); - Label catLbl = new Label(comboComp, SWT.NONE); - catLbl.setText("Category: "); - - gd = new GridData(200, SWT.DEFAULT); - categoryCbo = new Combo(comboComp, SWT.VERTICAL | SWT.DROP_DOWN - | SWT.BORDER | SWT.READ_ONLY); - categoryCbo.setLayoutData(gd); - categoryCbo.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - /* - * TODO - add code to update the information in the table - */ - } - }); + GridData gd = new GridData(SWT.FILL, SWT.CENTER, true, false); + caseNameLbl = new Label(comboComp, SWT.BORDER); + caseNameLbl.setLayoutData(gd); + return comboComp; } /** @@ -276,7 +304,7 @@ public class CaseCreationDlg extends CaveSWTDialog { private void createCompressionControls(Composite comp) { Composite compressionComp = new Composite(comp, SWT.NONE); GridLayout gl = new GridLayout(1, false); - GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); + GridData gd = new GridData(SWT.FILL, SWT.CENTER, true, false); compressionComp.setLayout(gl); compressionComp.setLayoutData(gd); @@ -284,7 +312,7 @@ public class CaseCreationDlg extends CaveSWTDialog { * Uncompressed file size label */ Composite compressionLblComp = new Composite(compressionComp, SWT.NONE); - gl = new GridLayout(3, false); + gl = new GridLayout(2, false); gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); compressionLblComp.setLayout(gl); compressionLblComp.setLayoutData(gd); @@ -294,9 +322,15 @@ public class CaseCreationDlg extends CaveSWTDialog { gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); uncompressSizeLbl = new Label(compressionLblComp, SWT.NONE); - uncompressSizeLbl.setText("1024 MB"); uncompressSizeLbl.setLayoutData(gd); + Label totSelectedLbl = new Label(compressionLblComp, SWT.NONE); + totSelectedLbl.setText("Total Selected Items: "); + + gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); + totalSelectedItemsLbl = new Label(compressionLblComp, SWT.NONE); + totalSelectedItemsLbl.setLayoutData(gd); + /* * Compression controls */ @@ -351,6 +385,9 @@ public class CaseCreationDlg extends CaveSWTDialog { handleFileSizeChangeSelection(); } }); + fileSizeCbo.add("MB"); + fileSizeCbo.add("GB"); + fileSizeCbo.select(0); } /** @@ -358,7 +395,7 @@ public class CaseCreationDlg extends CaveSWTDialog { */ private void createFileBrowserControls() { Composite fileBrowserComp = new Composite(shell, SWT.NONE); - GridLayout gl = new GridLayout(4, false); + GridLayout gl = new GridLayout(6, false); GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); fileBrowserComp.setLayout(gl); fileBrowserComp.setLayoutData(gd); @@ -378,13 +415,14 @@ public class CaseCreationDlg extends CaveSWTDialog { handleBrowserSelection(); } }); - } + browseBtn.setToolTipText("Select directory to place case."); - /** - * Create the table control. - */ - private void createTable() { - tableComp = new ArchiveTableComp(shell, TableType.Case); + Label stateLbl = new Label(fileBrowserComp, SWT.NONE); + stateLbl.setText("Full - Avaliable:"); + + locationStateLbl = new Label(fileBrowserComp, SWT.BORDER); + gd = new GridData(200, SWT.DEFAULT); + locationStateLbl.setLayoutData(gd); } /** @@ -398,22 +436,24 @@ public class CaseCreationDlg extends CaveSWTDialog { actionControlComp.setLayout(gl); actionControlComp.setLayoutData(gd); - Button exportBtn = new Button(actionControlComp, SWT.PUSH); - exportBtn.setText(" Export Case Config... "); - exportBtn.addSelectionListener(new SelectionAdapter() { + // TODO - Future implementation. + // Button exportBtn = new Button(actionControlComp, SWT.PUSH); + // exportBtn.setText(" Export Case Config... "); + // exportBtn.addSelectionListener(new SelectionAdapter() { + // + // @Override + // public void widgetSelected(SelectionEvent e) { + // + // } + // }); - @Override - public void widgetSelected(SelectionEvent e) { - - } - }); - - Button generateBtn = new Button(actionControlComp, SWT.PUSH); + generateBtn = new Button(actionControlComp, SWT.PUSH); generateBtn.setText(" Generate "); + generateBtn.setEnabled(false); generateBtn.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { - + generateCase(); } }); @@ -429,6 +469,49 @@ public class CaseCreationDlg extends CaveSWTDialog { }); } + /** + * Display modal dialog that performs the Generation of the case. + */ + private void generateCase() { + setCursorBusy(true); + File targetDir = (File) locationLbl.getData(); + File caseDir = (File) caseNameLbl.getData(); + Calendar startCal = getStart(); + Calendar endCal = getEnd(); + + List displayDatas = getSelectedData(); + boolean doCompress = compressChk.getSelection(); + boolean doMultiFiles = breakFilesChk.getSelection(); + int compressSize = fileSizeSpnr.getSelection(); + String sizeType = fileSizeCbo.getItem(fileSizeCbo.getSelectionIndex()); + + // Assume Model dialog. + GenerateCaseDlg dialog = new GenerateCaseDlg(shell, targetDir, caseDir, + startCal, endCal, displayDatas, doCompress, doMultiFiles, + compressSize, sizeType); + dialog.addJobChangeListener(new JobChangeAdapter() { + + @Override + public void done(IJobChangeEvent event) { + VizApp.runAsync(new Runnable() { + @Override + public void run() { + updateLocationState(); + } + }); + } + }); + dialog.setCloseCallback(new ICloseCallback() { + + @Override + public void dialogClosed(Object returnValue) { + setCursorBusy(false); + } + }); + dialog.open(); + + } + /** * Enable/Disable controls based on the compression check box. */ @@ -442,6 +525,36 @@ public class CaseCreationDlg extends CaveSWTDialog { breakFilesChk.setEnabled(compressChk.getSelection()); } + /** + * Bring up modal dialog to get the case's directory name. + */ + private void handleCaseNameSelection() { + Object o = locationLbl.getData(); + if (!(o instanceof File)) { + MessageDialog.openError(shell, "Error", + "Must select \"Case Location\"."); + return; + } + + File targetDir = (File) o; + // Assume modal dialog. + CaseNameDialog dialog = new CaseNameDialog(shell, targetDir); + dialog.setCloseCallback(new ICloseCallback() { + + @Override + public void dialogClosed(Object returnValue) { + if (returnValue instanceof File) { + File caseDir = (File) returnValue; + String caseName = caseDir.getAbsolutePath(); + caseNameLbl.setText(caseName); + caseNameLbl.setData(caseDir); + checkGenerateButton(); + } + } + }); + dialog.open(); + } + /** * Enable/Disable file size controls. * @@ -454,6 +567,16 @@ public class CaseCreationDlg extends CaveSWTDialog { fileSizeCbo.setEnabled(enabled); } + /** + * Enables the generate button will user has entered all needed elements. + */ + private void checkGenerateButton() { + if (generateBtn != null && !generateBtn.isDisposed()) { + generateBtn.setEnabled(locationLbl.getData() != null + && caseNameLbl.getData() != null && selectedItemsSize > 0); + } + } + /** * Action performed when the file size has changed. */ @@ -493,30 +616,51 @@ public class CaseCreationDlg extends CaveSWTDialog { if (dirName != null) { locationLbl.setText(trimDirectoryName(dirName)); locationLbl.setToolTipText(dirName); - locationLbl.setData(dirName); + locationLbl.setData(new File(dirName)); + caseNameCreate.setToolTipText(null); + caseNameLbl.setText(""); + caseNameLbl.setData(null); + updateLocationState(); + checkGenerateButton(); } } /** - * Add a separator line to the provided container. - * - * @param container - * Composite. - * @param orientation - * Vertical or horizontal orientation. + * Update location's state. */ - private void addSeparator(Composite container, int orientation) { - // Separator label - GridData gd; - - if (orientation == SWT.HORIZONTAL) { - gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); + private void updateLocationState() { + File dir = (File) locationLbl.getData(); + long totSpace = dir.getTotalSpace(); + long freeSpace = dir.getUsableSpace(); + long percentFull = (long) Math.round(((totSpace - freeSpace) * 100.0) + / totSpace); + String state = null; + Color bgColor = null; + Color fgColor = null; + Display display = shell.getDisplay(); + if (percentFull <= 84) { + state = "GOOD"; + bgColor = display.getSystemColor(SWT.COLOR_GREEN); + fgColor = display.getSystemColor(SWT.COLOR_BLACK); + } else if (percentFull <= 94) { + state = "CAUTION"; + bgColor = display.getSystemColor(SWT.COLOR_YELLOW); + fgColor = display.getSystemColor(SWT.COLOR_BLACK); + } else if (percentFull <= 97) { + state = "DANGER"; + bgColor = display.getSystemColor(SWT.COLOR_RED); + fgColor = display.getSystemColor(SWT.COLOR_BLACK); } else { - gd = new GridData(SWT.DEFAULT, SWT.FILL, false, true); + state = "FATAL"; + bgColor = display.getSystemColor(SWT.COLOR_DARK_MAGENTA); + fgColor = display.getSystemColor(SWT.COLOR_WHITE); } - Label sepLbl = new Label(container, SWT.SEPARATOR | orientation); - sepLbl.setLayoutData(gd); + String text = String.format("%1$3d%% %2$s - %3$s", percentFull, state, + SizeUtil.prettyByteSize(freeSpace)); + locationStateLbl.setText(text); + locationStateLbl.setBackground(bgColor); + locationStateLbl.setForeground(fgColor); } /** @@ -526,9 +670,16 @@ public class CaseCreationDlg extends CaveSWTDialog { * True for start time, false for end time. */ private void displayDateTimeControls(boolean startTimeFlag) { - AwipsCalendar ac = new AwipsCalendar(shell, 1); + + Date acDate = startTimeFlag ? startDate : endDate; + AwipsCalendar ac = new AwipsCalendar(shell, acDate, 1); + ac.setTimeZone(TimeUtil.newCalendar().getTimeZone()); Date date = (Date) ac.open(); + if (date == null) { + return; + } + if (startTimeFlag) { if (date.after(endDate)) { MessageBox mb = new MessageBox(shell, SWT.ICON_QUESTION @@ -538,6 +689,11 @@ public class CaseCreationDlg extends CaveSWTDialog { mb.open(); return; } + + if (!startDate.equals(date)) { + startDate = date; + resetSizes(); + } } else { if (date.before(startDate)) { MessageBox mb = new MessageBox(shell, SWT.ICON_QUESTION @@ -547,6 +703,10 @@ public class CaseCreationDlg extends CaveSWTDialog { mb.open(); return; } + if (!endDate.equals(date)) { + endDate = date; + resetSizes(); + } } if (startTimeFlag) { @@ -587,23 +747,98 @@ public class CaseCreationDlg extends CaveSWTDialog { return str; } - /******************************************************** - * TEST METHODS ****************************************************** + protected void setTotalSizeText(String text) { + uncompressSizeLbl.setText(text); + } + + protected void setTotalSelectedItems(int totalSelected) { + selectedItemsSize = totalSelected; + totalSelectedItemsLbl.setText("" + totalSelected); + checkGenerateButton(); + } + + /** + * Reset all entries to unknown size, recompute the sizes for the current + * display table and and other selected entries. */ - private void populateComboBoxes() { - archCfgCbo.add("Raw"); - archCfgCbo.add("Processed"); - archCfgCbo.select(0); + private void resetSizes() { + List selectedDatas = new ArrayList(); + for (String archiveName : archiveInfoMap.keySet()) { + ArchiveInfo archiveInfo = archiveInfoMap.get(archiveName); + for (String categoryName : archiveInfo.getCategoryNames()) { + CategoryInfo categoryInfo = archiveInfo.get(categoryName); + for (DisplayData displayData : categoryInfo + .getDisplayDataList()) { + displayData.setSize(DisplayData.UNKNOWN_SIZE); + if (displayData.isSelected()) { + selectedDatas.add(displayData); + } + } + } + } - categoryCbo.add("Radar"); - categoryCbo.add("Point"); - categoryCbo.add("Satellite"); - categoryCbo.select(0); + populateTableComp(); - fileSizeCbo.add("MB"); - fileSizeCbo.add("GB"); - fileSizeCbo.select(0); - fileSizeCbo - .setData(fileSizeCbo.getItem(fileSizeCbo.getSelectionIndex())); + if (selectedDatas.size() > 0) { + String archiveName = getSelectedArchiveName(); + String categoryName = getSelectedCategoryName(); + Calendar startCal = getStart(); + Calendar endCal = getEnd(); + + for (DisplayData displayData : selectedDatas) { + if (!displayData.isArchive(archiveName) + || !displayData.isCategory(categoryName)) { + sizeJob.queue(new SizeJobRequest(displayData, startCal, + endCal)); + } + } + } + } + + /** + * Get the data information on all selected items; not just the currently + * displayed table. + * + * @return selectedDatas + */ + private List getSelectedData() { + List selectedDatas = new ArrayList(); + for (String archiveName : archiveInfoMap.keySet()) { + ArchiveInfo archiveInfo = archiveInfoMap.get(archiveName); + for (String categoryName : archiveInfo.getCategoryNames()) { + CategoryInfo categoryInfo = archiveInfo.get(categoryName); + for (DisplayData displayData : categoryInfo + .getDisplayDataList()) { + if (displayData.isSelected()) { + selectedDatas.add(displayData); + } + } + } + } + return selectedDatas; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.archive.ui.AbstractArchiveDlg#getStart() + */ + // @Override + protected Calendar getStart() { + Calendar startCal = TimeUtil.newCalendar(); + startCal.setTimeInMillis(startDate.getTime()); + return startCal; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.uf.viz.archive.ui.AbstractArchiveDlg#getEnd() + */ + // @Override + protected Calendar getEnd() { + Calendar endCal = TimeUtil.newCalendar(); + endCal.setTimeInMillis(endDate.getTime()); + return endCal; } } diff --git a/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/CaseNameDialog.java b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/CaseNameDialog.java new file mode 100644 index 0000000000..60a5e16b54 --- /dev/null +++ b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/CaseNameDialog.java @@ -0,0 +1,189 @@ +/** + * 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.archive.ui; + +import java.io.File; + +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.KeyAdapter; +import org.eclipse.swt.events.KeyEvent; +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.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; + +import com.raytheon.viz.ui.dialogs.CaveSWTDialog; + +/** + * Dialog to obtain and verify a case name. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 5, 2013  1966       rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ + +public class CaseNameDialog extends CaveSWTDialog { + + /** The location directory. */ + private File locationDir; + + /** Text field for entering the case name's directory. */ + private Text caseNameText; + + /** Non-blocking modal constructor. */ + protected CaseNameDialog(Shell parent, File locationDir) { + super(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL, + CAVE.DO_NOT_BLOCK); + this.locationDir = locationDir; + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.viz.ui.dialogs.CaveSWTDialogBase#initializeComponents(org + * .eclipse.swt.widgets.Shell) + */ + @Override + protected void initializeComponents(Shell shell) { + Composite mainComp = new Composite(shell, SWT.NONE); + GridLayout gl = new GridLayout(1, false); + gl.marginHeight = 0; + gl.marginWidth = 0; + gl.horizontalSpacing = 0; + mainComp.setLayout(gl); + init(); + } + + /** + * create layout of the dialog. + */ + private void init() { + setText("Case Name"); + createFieldsComp(); + GuiUtil.addSeparator(shell, SWT.HORIZONTAL); + createBottomActionButtons(); + } + + /** + * The xomposite with case name text field. + */ + private void createFieldsComp() { + Composite fieldComp = new Composite(shell, SWT.NONE); + GridLayout gl = new GridLayout(2, false); + GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); + fieldComp.setLayout(gl); + fieldComp.setLayoutData(gd); + + Label nameLbl = new Label(fieldComp, SWT.LEFT); + nameLbl.setText("Name: "); + + caseNameText = new Text(fieldComp, SWT.SINGLE); + gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); + gd.minimumWidth = 200; + caseNameText.setLayoutData(gd); + caseNameText.addKeyListener(new KeyAdapter() { + + @Override + public void keyReleased(KeyEvent e) { + super.keyReleased(e); + if (e.character == SWT.CR || e.character == SWT.KEYPAD_CR) { + if (verifySelection()) { + close(); + } + } + } + }); + } + + /** + * The composite with the action buttons. + */ + private void createBottomActionButtons() { + Composite actionControlComp = new Composite(shell, SWT.NONE); + GridLayout gl = new GridLayout(2, false); + GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); + actionControlComp.setLayout(gl); + actionControlComp.setLayoutData(gd); + + Button okBtn = new Button(actionControlComp, SWT.PUSH); + okBtn.setText(" OK "); + okBtn.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + if (verifySelection()) { + close(); + } + } + }); + + Button cancelBtn = new Button(actionControlComp, SWT.PUSH); + cancelBtn.setText(" Cancel "); + cancelBtn.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + close(); + } + }); + } + + /** + * Validate the case's directory does not exist and set the return value + * when it doesn't exist. + * + * @return true when case's directory does not exist. + */ + private boolean verifySelection() { + String caseName = caseNameText.getText().trim(); + if (caseName.length() == 0) { + MessageDialog.openError(shell, "Error", "Enter a case name."); + return false; + } + + File caseDir = new File(locationDir, caseName); + if (caseDir.exists()) { + MessageDialog.openError(shell, "Error", + "Case already exists choose another name."); + caseNameText.selectAll(); + caseNameText.setFocus(); + return false; + } + + setReturnValue(caseDir); + return true; + } + +} diff --git a/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/GenerateCaseDlg.java b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/GenerateCaseDlg.java new file mode 100644 index 0000000000..5ec5cfa75a --- /dev/null +++ b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/GenerateCaseDlg.java @@ -0,0 +1,465 @@ +/** + * 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.archive.ui; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; + +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.IJobChangeListener; +import org.eclipse.core.runtime.jobs.Job; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.ShellAdapter; +import org.eclipse.swt.events.ShellEvent; +import org.eclipse.swt.graphics.Color; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Button; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.ProgressBar; +import org.eclipse.swt.widgets.Shell; + +import com.raytheon.uf.common.archive.config.ArchiveConfigManager; +import com.raytheon.uf.common.archive.config.DisplayData; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.uf.common.util.FileUtil; +import com.raytheon.uf.viz.core.VizApp; +import com.raytheon.viz.ui.dialogs.CaveSWTDialog; + +/** + * Class to show progress of creating a case. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 3, 2013  1966       rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrelGenerateJob + * @version 1.0 + */ + +public class GenerateCaseDlg extends CaveSWTDialog { + private final IUFStatusHandler statusHandler = UFStatus + .getHandler(GenerateCaseDlg.class); + + /** Use to display the current state of the case generation. */ + private Label stateLbl; + + /** Progress bar to indicate activity. */ + private ProgressBar progressBar; + + /** Stops the case generation leaving it in an unknown state. */ + private Button cancelBtn; + + /** Active have generation is finish or has an error. */ + private Button closeBtn; + + /** The main destination directory. */ + private final File targetDir; + + /** + * The case's destination directory. Assumed to be a sub-directory of + * targetDir. + */ + private final File caseDir; + + /** Starting time for the case. */ + private final Calendar startCal; + + /** End time for the case. */ + private final Calendar endCal; + + /** Data list for the case. */ + private final List sourceDataList; + + /** When true compress the case directory. */ + private final boolean doCompress; + + /** When true break the compress file into multliple files. */ + private final boolean doMultiFiles; + + /** The compress size for muliple files. */ + private final int compressSize; + + /** Assumed to be MG or GB to indicate scaling factor for compressSize. */ + private final String sizeType; + + /** Job to perform the case generation off of the UI thread. */ + private GenerateJob generateJob; + + /** Shorten case name to use in status message. */ + private final String caseName; + + /** Listeners to add to the job when scheduled. */ + private final List jobListeners = new ArrayList(); + + /** Data manager. */ + private final ArchiveConfigManager archiveManager = ArchiveConfigManager + .getInstance(); + + /** + * Constructor. + * + * @param parentShell + * @param targetDir + * @param caseDir + * @param startCal + * @param endCal + * @param sourceList + * @param doCompress + * @param doMultiFiles + * @param compressSize + * @param sizeType + */ + protected GenerateCaseDlg(Shell parentShell, File targetDir, File caseDir, + Calendar startCal, Calendar endCal, List sourceList, + boolean doCompress, boolean doMultiFiles, int compressSize, + String sizeType) { + super(parentShell, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL, + CAVE.DO_NOT_BLOCK); + this.targetDir = targetDir; + this.caseDir = caseDir; + this.startCal = startCal; + this.endCal = endCal; + this.sourceDataList = new ArrayList(sourceList); + this.doCompress = doCompress; + this.doMultiFiles = doMultiFiles; + this.compressSize = compressSize; + this.sizeType = sizeType; + this.caseName = caseDir.getAbsolutePath().substring( + targetDir.getAbsolutePath().length() + 1); + setText("Generating - " + caseName); + } + + /** + * Add a job listener. + * + * @param listener + */ + protected void addJobChangeListener(IJobChangeListener listener) { + jobListeners.add(listener); + } + + /** + * Remve a job listener. + * + * @param listener + */ + protected void removeJobChangeListener(IJobChangeListener listener) { + jobListeners.remove(listener); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.viz.ui.dialogs.CaveSWTDialogBase#initializeComponents(org + * .eclipse.swt.widgets.Shell) + */ + @Override + protected void initializeComponents(Shell shell) { + Composite mainComp = new Composite(shell, SWT.NONE); + GridLayout gl = new GridLayout(1, false); + gl.marginHeight = 0; + gl.marginWidth = 0; + gl.horizontalSpacing = 0; + mainComp.setLayout(gl); + + init(); + } + + /** + * Set up main layout. + */ + private void init() { + createProgress(); + GuiUtil.addSeparator(shell, SWT.HORIZONTAL); + createBottomActionButtons(); + } + + /** + * The progress component. + */ + private void createProgress() { + Composite progComp = new Composite(shell, SWT.NONE); + GridLayout gl = new GridLayout(1, false); + progComp.setLayout(gl); + + GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); + gd.minimumWidth = 300; + stateLbl = new Label(shell, SWT.BORDER | SWT.CENTER); + stateLbl.setLayoutData(gd); + stateLbl.setText("state of progress goes here."); + + progressBar = new ProgressBar(shell, SWT.DEFAULT); + gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); + progressBar.setLayoutData(gd); + } + + /** + * Component for the action buttons. + */ + private void createBottomActionButtons() { + Composite actionComp = new Composite(shell, SWT.NONE); + GridLayout gl = new GridLayout(2, false); + actionComp.setLayout(gl); + + cancelBtn = new Button(actionComp, SWT.PUSH); + cancelBtn.setText(" Cancel "); + cancelBtn.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + if (generateJob != null && generateJob.getState() != Job.NONE) { + generateJob.cancel(); + } + + close(); + } + }); + + closeBtn = new Button(actionComp, SWT.PUSH); + closeBtn.setText(" Close "); + closeBtn.setEnabled(false); + closeBtn.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + close(); + } + }); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.viz.ui.dialogs.CaveSWTDialog#preOpened() + */ + @Override + protected void preOpened() { + super.preOpened(); + + generateJob = new GenerateJob(); + for (IJobChangeListener listener : jobListeners) { + generateJob.addJobChangeListener(listener); + } + + generateJob.schedule(); + shell.addShellListener(new ShellAdapter() { + + @Override + public void shellClosed(ShellEvent e) { + if (generateJob != null && generateJob.getState() != Job.NONE) { + e.doit = false; + } + } + }); + } + + /** + * Allow a non-UI thread to update the state label. + * + * @param message + * @param tooltip + */ + private void setStateLbl(final String message, final String tooltip) { + VizApp.runAsync(new Runnable() { + @Override + public void run() { + if (!stateLbl.isDisposed()) { + stateLbl.setText(message); + stateLbl.setToolTipText(tooltip); + } + } + }); + } + + /** + * Allow a non-UI thread to update the progress bar and background of the + * state label when there is an error. + * + * @param value + * @param state + */ + private void setProgressBar(final int value, final int state) { + VizApp.runAsync(new Runnable() { + + @Override + public void run() { + if (!progressBar.isDisposed()) { + int val = value; + if (val < progressBar.getMinimum()) { + val = progressBar.getMinimum(); + } else if (val >= progressBar.getMaximum()) { + val = progressBar.getMaximum(); + closeBtn.setEnabled(true); + cancelBtn.setEnabled(false); + } + progressBar.setSelection(val); + progressBar.setState(state); + progressBar.setVisible(val != progressBar.getMaximum()); + Color bgColor = null; + if (state == SWT.ERROR) { + bgColor = shell.getDisplay().getSystemColor( + SWT.COLOR_RED); + } + stateLbl.setBackground(bgColor); + } + } + }); + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.viz.ui.dialogs.CaveSWTDialogBase#disposed() + */ + @Override + protected void disposed() { + if (generateJob != null && generateJob.getState() != Job.NONE) { + generateJob.cancel(); + } + } + + /** + * The performs the work of generating the case on a non-UI thread. + */ + private class GenerateJob extends Job { + boolean shutdown = false; + + public GenerateJob() { + super("Generate Job"); + } + + @Override + protected IStatus run(IProgressMonitor monitor) { + if (monitor.isCanceled()) { + return Status.OK_STATUS; + } + + setStateLbl("Creating: " + caseDir.getName(), + caseDir.getAbsolutePath()); + if (caseDir.exists()) { + setStateLbl("Case exists: " + caseName, + caseDir.getAbsolutePath()); + setProgressBar(100, SWT.ERROR); + return Status.OK_STATUS; + } + + if (!caseDir.mkdirs()) { + setStateLbl("Unable to create case: " + caseName, + caseDir.getAbsolutePath()); + setProgressBar(100, SWT.ERROR); + return Status.OK_STATUS; + } + + if (shutdown) { + return Status.OK_STATUS; + } + + for (DisplayData displayData : sourceDataList) { + if (shutdown) { + return Status.OK_STATUS; + } + + setStateLbl( + "Copying \"" + displayData.getDisplayLabel() + "\"", + null); + String rootDir = displayData.getRootDir(); + int beginIndex = rootDir.length(); + + List files = archiveManager.getDisplayFiles(displayData, + startCal, endCal); + for (File source : files) { + if (shutdown) { + return Status.OK_STATUS; + } + + String name = source.getAbsolutePath(); + String relativePath = name.substring(beginIndex); + + setStateLbl("Copy: " + relativePath, name); + File destination = new File(caseDir, relativePath); + try { + if (source.isDirectory()) { + destination.mkdirs(); + FileUtil.copyDirectory(source, destination); + } else { + File destParent = destination.getParentFile(); + destParent.mkdirs(); + FileUtil.copyFile(source, destination); + } + } catch (IOException e) { + statusHandler.handle(Priority.PROBLEM, + e.getLocalizedMessage(), e); + } + } + } + + if (!doCompress) { + setProgressBar(100, SWT.NORMAL); + setStateLbl("Created: " + caseName, caseDir.getAbsolutePath()); + return Status.OK_STATUS; + } + + if (shutdown) { + return Status.OK_STATUS; + } + + if (doMultiFiles) { + setProgressBar(100, SWT.NORMAL); + String message = "Compress into multifiles NYI."; + setStateLbl(message, null); + } else { + setProgressBar(100, SWT.NORMAL); + String message = "Compress into one file NYI"; + setStateLbl(message, null); + } + + return Status.OK_STATUS; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.core.runtime.jobs.Job#canceling() + */ + @Override + protected void canceling() { + shutdown = true; + generateJob = null; + } + } +} diff --git a/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/GuiUtil.java b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/GuiUtil.java new file mode 100644 index 0000000000..4d02e65d0a --- /dev/null +++ b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/GuiUtil.java @@ -0,0 +1,70 @@ +/** + * 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.archive.ui; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; + +/** + * Common methods used in the dialogs. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 6, 2013  1966       rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ + +public class GuiUtil { + private GuiUtil() { + } + + /** + * Add a separator line to the provided container. + * + * @param container + * Composite. + * @param orientation + * Vertical or horizontal orientation. + */ + public static void addSeparator(Composite container, int orientation) { + // Separator label + GridData gd; + + if (orientation == SWT.HORIZONTAL) { + gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); + } else { + gd = new GridData(SWT.DEFAULT, SWT.FILL, false, true); + } + + Label sepLbl = new Label(container, SWT.SEPARATOR | orientation); + sepLbl.setLayoutData(gd); + } + +} diff --git a/edexOsgi/com.raytheon.uf.common.archive/src/com/raytheon/uf/common/archive/ArchiveManagerFactory.java b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/IModifyListener.java similarity index 75% rename from edexOsgi/com.raytheon.uf.common.archive/src/com/raytheon/uf/common/archive/ArchiveManagerFactory.java rename to cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/IModifyListener.java index 92d92a82bf..835aa0d714 100644 --- a/edexOsgi/com.raytheon.uf.common.archive/src/com/raytheon/uf/common/archive/ArchiveManagerFactory.java +++ b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/IModifyListener.java @@ -17,10 +17,10 @@ * See the AWIPS II Master Rights File ("Master Rights File.pdf") for * further licensing information. **/ -package com.raytheon.uf.common.archive; +package com.raytheon.uf.viz.archive.ui; /** - * Factory for accessing an archive CategoryManager. + * A Listner to inform when class is modified. * *
  * 
@@ -28,18 +28,17 @@ package com.raytheon.uf.common.archive;
  * 
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
- * May 06, 2013 1966       bgonzale    Initial creation
+ * Jun 18, 2013 1966       rferrel     Initial creation
  * 
  * 
* - * @author bgonzale + * @author rferrel * @version 1.0 */ -public class ArchiveManagerFactory { - - public static IArchiveManager getManager() { - return null; - } - +public interface IModifyListener { + /* + * Method called to notify listener that a modification has happened. + */ + public void modified(); } diff --git a/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/RetentionHours.java b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/RetentionHours.java new file mode 100644 index 0000000000..2edc296c97 --- /dev/null +++ b/cave/com.raytheon.uf.viz.archive/src/com/raytheon/uf/viz/archive/ui/RetentionHours.java @@ -0,0 +1,258 @@ +/** + * 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.archive.ui; + +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +import org.eclipse.swt.events.SelectionAdapter; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.widgets.Combo; +import org.eclipse.swt.widgets.Spinner; + +import com.raytheon.uf.common.time.util.TimeUtil; + +/** + * Convenience class for taking retention hours and converting to days/hours. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * May 2, 2013  1966       rferrel     Initial creation
+ * 
+ * 
+ * + * @author rferrel + * @version 1.0 + */ + +public class RetentionHours { + + /** Minimum value for the spinner. */ + private final int minUnit; + + /** The retention hours. */ + private int retentionHours; + + /** Spinner for the time assume hours or days. */ + private Spinner timeSpnr; + + /** Combo box assume to determine use of Hours or Days. */ + private Combo timeUnitCombo; + + /** + * Keep track of previous time unit so recalculation only done when changed. + */ + private int prevTimeUnitSelected = 0; + + /** + * Set when user modified values. + */ + private boolean modifyState = false; + + /** + * Listeners to inform when user performs a modification. + */ + private final List listeners = new CopyOnWriteArrayList(); + + /** + * Constructor with default 7 day retention. + */ + public RetentionHours(int minUnit, Spinner timeSpnr, Combo timeUnitCombo) { + this.minUnit = minUnit; + this.timeSpnr = timeSpnr; + this.timeUnitCombo = timeUnitCombo; + init(); + } + + /** + * Set up Listeners on the combo boxes for time conversion. + */ + private void init() { + timeSpnr.setMinimum(minUnit); + timeSpnr.addSelectionListener(new SelectionAdapter() { + + @Override + public void widgetSelected(SelectionEvent e) { + updateAndCheckTimeSelection(); + } + }); + + timeUnitCombo.removeAll(); + timeUnitCombo.add("Hours"); + timeUnitCombo.add("Days"); + timeUnitCombo.select(prevTimeUnitSelected); + + timeUnitCombo.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + if (prevTimeUnitSelected != timeUnitCombo.getSelectionIndex()) { + prevTimeUnitSelected = timeUnitCombo.getSelectionIndex(); + handleTimeUnitSelection(); + updateAndCheckTimeSelection(); + } + } + }); + timeUnitCombo.setData(timeUnitCombo.getItem(timeUnitCombo + .getSelectionIndex())); + } + + /** + * Update the retention hours and determine if modification listeners should + * be notified. + */ + private void updateAndCheckTimeSelection() { + // Make sure this is called so retention hours is updated properly. + boolean modified = handleTimeSelection(); + + // Do notification when state becomes true. + if (!modifyState && modified) { + modifyState = true; + for (IModifyListener iModifyListener : listeners) { + iModifyListener.modified(); + } + } + } + + /** + * Get retention in hours. + * + * @return + */ + public int getHours() { + return retentionHours; + } + + /** + * Set number hours of retention. + * + * @param hours + */ + public void setHours(int hours) { + if (hours < minUnit) { + hours = minUnit; + } + + retentionHours = hours; + int time = retentionHours; + if (timeUnitCombo.getItem(timeUnitCombo.getSelectionIndex()).equals( + "Days")) { + time /= TimeUtil.HOURS_PER_DAY; + if (time < minUnit) { + time = minUnit; + } + } + + timeSpnr.setSelection(time); + + // Based on the time unit retentionHours may need updating. + handleTimeSelection(); + } + + /** + * Handle the retention selection for both minimum and extended retention. + * + * @param timeUnitCombo + * Retention combo box. + * @param timeSpinner + * Retention spinner. + * @return hours entered if changed; -1 if not changed + */ + private void handleTimeUnitSelection() { + int time = 0; + + if (timeUnitCombo.getItem(timeUnitCombo.getSelectionIndex()).equals( + "Hours")) { + time = convertTime(true, timeSpnr.getSelection()); + } else { + time = convertTime(false, timeSpnr.getSelection()); + } + + timeSpnr.setSelection(time); + timeUnitCombo.setData(timeUnitCombo.getItem(timeUnitCombo + .getSelectionIndex())); + } + + /** + * Covert time from either hours to days or days to hours. + * + * @param daysToHours + * Flag indicating how to convert the time. + * @param time + * Time to be converted. + * @return The converted time. + */ + private int convertTime(boolean daysToHours, int time) { + int convertedTime = 0; + + if (daysToHours) { + convertedTime = time * TimeUtil.HOURS_PER_DAY; + retentionHours = convertedTime; + } else { + convertedTime = time / TimeUtil.HOURS_PER_DAY; + retentionHours = convertedTime * TimeUtil.HOURS_PER_DAY; + } + return convertedTime; + } + + /** + * Adjust retention hours based on combo boxes current values. + */ + protected boolean handleTimeSelection() { + int time = timeSpnr.getSelection(); + boolean modified = false; + if (timeUnitCombo.getItem(timeUnitCombo.getSelectionIndex()).equals( + "Days")) { + time *= TimeUtil.HOURS_PER_DAY; + } + + if (retentionHours != time) { + retentionHours = time; + modified = true; + } + return modified; + } + + /** + * Reset the modify state. + */ + public void clearModified() { + modifyState = false; + } + + /** + * + * @param iModifyListener + */ + public void addModifyListener(IModifyListener iModifyListener) { + listeners.add(iModifyListener); + } + + /** + * + * @param iModifyListener + */ + public void removeModifyListener(IModifyListener iModifyListener) { + listeners.remove(iModifyListener); + } +} diff --git a/cave/com.raytheon.uf.viz.core.feature/feature.xml b/cave/com.raytheon.uf.viz.core.feature/feature.xml index 447a7c642c..62ff17a95b 100644 --- a/cave/com.raytheon.uf.viz.core.feature/feature.xml +++ b/cave/com.raytheon.uf.viz.core.feature/feature.xml @@ -194,4 +194,10 @@ install-size="0" version="0.0.0"/> + + diff --git a/cave/com.raytheon.uf.viz.core/res/spring/viz.xml b/cave/com.raytheon.uf.viz.core/res/spring/viz.xml index d717b020e3..ceb8bdc277 100644 --- a/cave/com.raytheon.uf.viz.core/res/spring/viz.xml +++ b/cave/com.raytheon.uf.viz.core/res/spring/viz.xml @@ -3,10 +3,10 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util" - xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd - http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd + http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/util - http://www.springframework.org/schema/util/spring-util-2.5.xsd"> + http://www.springframework.org/schema/util/spring-util-3.1.xsd"> diff --git a/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/RecordFactory.java b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/RecordFactory.java index 2caf926800..1fbb05fc3a 100644 --- a/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/RecordFactory.java +++ b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/RecordFactory.java @@ -153,6 +153,15 @@ public class RecordFactory implements IPluginClassMapper { map.put("dataURI", dataURI); return map; } catch (Exception e) { + // if this exception was caused by NoPlugin then throw that so that + // caller knows exactly why this happened. + Throwable cause = e.getCause(); + while (cause != null) { + if (cause instanceof NoPluginException) { + throw (NoPluginException) cause; + } + cause = cause.getCause(); + } throw new VizException("Unable to create property map for " + dataURI, e); } @@ -251,7 +260,7 @@ public class RecordFactory implements IPluginClassMapper { try { return getPluginClass(pluginName); } catch (NoPluginException e) { - throw new PluginException(e.getLocalizedMessage()); + throw new PluginException(e.getLocalizedMessage(), e); } } } \ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/auth/IUserManager.java b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/auth/IUserManager.java index fc0d61f4ec..212f7bc1da 100644 --- a/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/auth/IUserManager.java +++ b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/auth/IUserManager.java @@ -37,6 +37,7 @@ import com.raytheon.uf.viz.core.requests.INotAuthHandler; * ------------ ---------- ----------- -------------------------- * May 21, 2010 mschenke Initial creation * Nov 06, 2012 1302 djohnson Add ability to get roles/permissions for an application. + * Jun 07, 2013 1981 mpduff Add ability to update with the user id as a string. * * * @@ -85,4 +86,14 @@ public interface IUserManager { * @return the list of roles */ List getRoles(String application); + + /** + * Update the user object with the authentication data update + * + * @param userId + * User's id + * @param authData + * User's authentication data + */ + void updateUserObject(String userId, IAuthenticationData authData); } diff --git a/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/auth/UserController.java b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/auth/UserController.java index c63fa10b72..efc1d93cc8 100644 --- a/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/auth/UserController.java +++ b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/auth/UserController.java @@ -55,6 +55,7 @@ import com.raytheon.uf.viz.core.requests.INotAuthHandler; * Nov 06, 2012 1302 djohnson Add ability to retrieve the {@link IUserManager}. * Jan 04, 2013 1451 djohnson Move static block code to an implementation of an interface. * Mar 21, 2013 1794 djohnson ServiceLoaderUtil now requires the requesting class. + * Jun 07, 2013 1981 mpduff Add ability to update with the user id as a string. * * * @@ -166,6 +167,12 @@ public class UserController { return Collections.emptyList(); } + @Override + public void updateUserObject(String userId, + IAuthenticationData authData) { + + } + }; } return manager; @@ -194,6 +201,16 @@ public class UserController { manager.updateUserObject(manager.getUserObject(), data); } + /** + * Update the user's id. + * + * @param userID + * The user id + */ + public static void updateUserData(String userID) { + manager.updateUserObject(userID, null); + } + public static INotAuthHandler getNotAuthHandler() { return manager.getNotAuthHandler(); } diff --git a/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/comm/CaveHttpsCredentialsHandler.java b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/comm/CaveHttpsCredentialsHandler.java index b39ad87a26..2036322469 100644 --- a/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/comm/CaveHttpsCredentialsHandler.java +++ b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/comm/CaveHttpsCredentialsHandler.java @@ -20,6 +20,7 @@ package com.raytheon.uf.viz.core.comm; import com.raytheon.uf.common.comm.IHttpsCredentialsHandler; +import com.raytheon.uf.viz.core.auth.UserController; /** * Cave implementation of the IHttpsCredentialsHandler. Displays the Cave login @@ -31,7 +32,8 @@ import com.raytheon.uf.common.comm.IHttpsCredentialsHandler; * * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * Mar 4, 2013 1786 mpduff Initial creation + * Mar 04, 2013 1786 mpduff Initial creation. + * Jun 07, 2013 1981 mpduff Save user's username in UserController. * * * @@ -52,6 +54,9 @@ public class CaveHttpsCredentialsHandler implements IHttpsCredentialsHandler { } HttpsLoginDlg login = new HttpsLoginDlg(message); login.open(); - return login.getCredentials(); + String[] credentials = login.getCredentials(); + // Save off the user's username in the UserController + UserController.updateUserData(credentials[0]); + return credentials; } } diff --git a/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/rsc/AbstractRequestableResourceData.java b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/rsc/AbstractRequestableResourceData.java index a25b6313fb..8c8d8f0cf3 100644 --- a/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/rsc/AbstractRequestableResourceData.java +++ b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/rsc/AbstractRequestableResourceData.java @@ -292,6 +292,8 @@ public abstract class AbstractRequestableResourceData extends } } this.fireChangeListeners(ChangeType.DATA_UPDATE, updateData); + } else { + this.fireChangeListeners(ChangeType.DATA_UPDATE, updateData); } } diff --git a/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/rsc/ResourceCatalog.java b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/rsc/ResourceCatalog.java index 3ab303deaf..aab670da78 100644 --- a/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/rsc/ResourceCatalog.java +++ b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/rsc/ResourceCatalog.java @@ -45,8 +45,10 @@ import com.raytheon.uf.viz.core.rsc.updater.DataUpdateTree; * SOFTWARE HISTORY * * Date Ticket# Engineer Description - * ------------ ---------- ----------- -------------------------- - * 7/1/06 chammack Initial Creation. + * ------------ ---------- ----------- -------------------------- + * Jul 01, 2006 chammack Initial Creation. + * Jun 07, 2013 2034 bsteffen Clear all locks in resource catalog + * before runAsync. * * * @@ -127,28 +129,34 @@ public class ResourceCatalog implements IDisposeListener { * @param displayID * the id of the display */ - public synchronized void removeResource( + public void removeResource( final AbstractVizResource resource, String displayID) { - Set list = theMapping.get(resource); - if (list != null) { - list.remove(displayID); - if (list.size() == 0) { - // Only dispose of resources if they have been initialized - if (resource.getStatus() == ResourceStatus.INITIALIZED) { - // this needs to be async, otherwise other components like - // gfe can deadlock when this blocks but the UI thread is - // blocked waiting on a different lock - VizApp.runAsync(new Runnable() { - @Override - public void run() { - resource.dispose(); - } - }); - } else { - disposed(resource); + boolean dispose = false; + synchronized (this) { + Set list = theMapping.get(resource); + if (list != null) { + list.remove(displayID); + if (list.size() == 0) { + // Only dispose of resources if they have been initialized + if (resource.getStatus() == ResourceStatus.INITIALIZED) { + dispose = true; + } else { + disposed(resource); + } } } } + if (dispose) { + // this needs to be async outside the synchronized block, otherwise + // other components like gfe and warngen can deadlock when this + // blocks but the UI thread is blocked waiting on a different lock + VizApp.runAsync(new Runnable() { + @Override + public void run() { + resource.dispose(); + } + }); + } } /* @@ -162,7 +170,9 @@ public class ResourceCatalog implements IDisposeListener { public void disposed(AbstractVizResource resource) { // Nothing points to this resource // remove it from the map, and invoke dispose. - theMapping.remove(resource); + synchronized (this) { + theMapping.remove(resource); + } if (resource instanceof IResourceGroup) { ((IResourceGroup) resource).getResourceList().clear(); diff --git a/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/rsc/capabilities/Capabilities.java b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/rsc/capabilities/Capabilities.java index 73b2f0f2f6..fb32a90add 100644 --- a/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/rsc/capabilities/Capabilities.java +++ b/cave/com.raytheon.uf.viz.core/src/com/raytheon/uf/viz/core/rsc/capabilities/Capabilities.java @@ -52,6 +52,7 @@ import com.raytheon.uf.viz.core.rsc.AbstractResourceData; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Feb 2, 2009 chammack Initial creation + * Jun 7, 2013 2074 mnash Fix for null capabilities trying to be added * * * @@ -191,7 +192,9 @@ public class Capabilities implements Iterable { collection).iterator(); while (collectionIterator.hasNext()) { AbstractCapability cap = collectionIterator.next(); - this.backingMap.put(cap.getClass(), cap); + if (cap != null) { + this.backingMap.put(cap.getClass(), cap); + } } } diff --git a/cave/com.raytheon.uf.viz.cots.feature/feature.xml b/cave/com.raytheon.uf.viz.cots.feature/feature.xml index 93c524c534..a99fb60162 100644 --- a/cave/com.raytheon.uf.viz.cots.feature/feature.xml +++ b/cave/com.raytheon.uf.viz.cots.feature/feature.xml @@ -43,8 +43,7 @@ id="com.sun.jna" download-size="0" install-size="0" - version="0.0.0" - unpack="false"/> + version="0.0.0"/> + version="0.0.0"/> + + + + diff --git a/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/actions/OpenAWIPSProcedure.java b/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/actions/OpenAWIPSProcedure.java index 306883f180..5d743cc132 100644 --- a/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/actions/OpenAWIPSProcedure.java +++ b/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/actions/OpenAWIPSProcedure.java @@ -47,7 +47,7 @@ import com.raytheon.viz.ui.dialogs.ICloseCallback; * Sep 13, 2007 chammack Initial Creation. * Oct 16, 2012 1229 rferrel Change to use ProcedureDlg.displayDialog. * Oct 16, 2012 1229 rferrel Changes for non-blocking ProcedureListDlg. - * + * Jun 7, 2013 2074 mnash Don't open the dialog if no procedures are deserialized * * * @author chammack @@ -77,10 +77,12 @@ public class OpenAWIPSProcedure extends AbstractHandler { File f = selectedFile.getFile(); Procedure p = (Procedure) LoadSerializedXml .deserialize(f); - ProcedureDlg.displayDialog(LocalizationUtil - .extractName(selectedFile.getName()), p, - VizWorkbenchManager.getInstance() - .getCurrentWindow().getShell()); + if (p != null) { + ProcedureDlg.displayDialog(LocalizationUtil + .extractName(selectedFile.getName()), p, + VizWorkbenchManager.getInstance() + .getCurrentWindow().getShell()); + } } dialog = null; } diff --git a/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/dialogs/procedures/ProcedureDlg.java b/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/dialogs/procedures/ProcedureDlg.java index 120c7fe66e..f50665e65d 100644 --- a/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/dialogs/procedures/ProcedureDlg.java +++ b/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/dialogs/procedures/ProcedureDlg.java @@ -75,6 +75,7 @@ import com.raytheon.uf.viz.core.procedures.Procedure; import com.raytheon.uf.viz.core.rsc.AbstractRequestableResourceData; import com.raytheon.uf.viz.core.rsc.AbstractResourceData; import com.raytheon.uf.viz.core.rsc.AbstractVizResource; +import com.raytheon.uf.viz.core.rsc.ResourceList; import com.raytheon.uf.viz.d2d.ui.dialogs.procedures.ProcedureComm.BundlePair; import com.raytheon.viz.ui.HistoryList; import com.raytheon.viz.ui.UiUtil; @@ -100,7 +101,7 @@ import com.raytheon.viz.ui.editor.AbstractEditor; * Jan 15, 2013 DR 15699 D. Friedman Prompt for save when close button clicked. * Jan 16, 2013 DR 15367 D. Friedman Enable save button for Up/Down changes. * Feb 25, 2013 1640 bsteffen Dispose old display in BundleLoader - * + * Jun 7, 2013 2074 mnash Remove resource if doesn't instantiate correctly * * * @author unknown @@ -193,15 +194,26 @@ public class ProcedureDlg extends CaveSWTDialog { if (p != null && p.getBundles() != null) { Bundle[] bund = p.getBundles(); for (Bundle b : bund) { + // remove any bad resource pairs from each display + for (AbstractRenderableDisplay display : b.getDisplays()) { + ResourceList rList = display.getDescriptor() + .getResourceList(); + // modify the resource list so that we remove any null + // resource datas + for (ResourcePair rp : rList) { + if (rp.getResourceData() == null) { + rList.remove(rp); + } + } + } // Check to see if frozen for (AbstractRenderableDisplay display : b.getDisplays()) { - for (ResourcePair rp : display.getDescriptor() - .getResourceList()) { - if (rp.getResourceData() != null) { - if (rp.getResourceData().isFrozen()) { - frozen = true; - break; - } + ResourceList rList = display.getDescriptor() + .getResourceList(); + for (ResourcePair rp : rList) { + if (rp.getResourceData().isFrozen()) { + frozen = true; + break; } } if (frozen) { @@ -958,8 +970,7 @@ public class ProcedureDlg extends CaveSWTDialog { } } - private void handleCloseRequest() - { + private void handleCloseRequest() { if (saved) { close(); } else { @@ -972,7 +983,8 @@ public class ProcedureDlg extends CaveSWTDialog { * to close it */ private void showConfirmSaveDlg() { - CaveSWTDialog dlg = new CaveSWTDialog(shell, SWT.DIALOG_TRIM | SWT.PRIMARY_MODAL, CAVE.DO_NOT_BLOCK) { + CaveSWTDialog dlg = new CaveSWTDialog(shell, SWT.DIALOG_TRIM + | SWT.PRIMARY_MODAL, CAVE.DO_NOT_BLOCK) { @Override protected void initializeComponents(Shell shell) { diff --git a/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/dialogs/procedures/ProcedureListDlg.java b/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/dialogs/procedures/ProcedureListDlg.java index 51411554db..664d74ca44 100644 --- a/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/dialogs/procedures/ProcedureListDlg.java +++ b/cave/com.raytheon.uf.viz.d2d.ui/src/com/raytheon/uf/viz/d2d/ui/dialogs/procedures/ProcedureListDlg.java @@ -19,6 +19,8 @@ **/ package com.raytheon.uf.viz.d2d.ui.dialogs.procedures; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IMenuListener; import org.eclipse.jface.action.IMenuManager; @@ -32,6 +34,7 @@ import org.eclipse.swt.events.MouseListener; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Cursor; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; @@ -39,6 +42,7 @@ import org.eclipse.swt.layout.RowData; import org.eclipse.swt.layout.RowLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; @@ -52,6 +56,7 @@ 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.localization.PathManagerFactory; +import com.raytheon.uf.viz.core.VizApp; import com.raytheon.viz.ui.dialogs.CaveSWTDialog; /** @@ -175,7 +180,10 @@ public class ProcedureListDlg extends CaveSWTDialog { * @param mainComp */ protected void createTextComp(Composite mainComp) { - Composite textComp = new Composite(mainComp, SWT.NONE); + final Cursor cursor = getShell().getCursor(); + getShell().setCursor( + Display.getCurrent().getSystemCursor(SWT.CURSOR_WAIT)); + final Composite textComp = new Composite(mainComp, SWT.NONE); textComp.setLayout(new GridLayout(1, true)); GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); gd.widthHint = 150; @@ -227,24 +235,41 @@ public class ProcedureListDlg extends CaveSWTDialog { } }); - fileTree = populateDataList(treeViewer); + Job job = new Job("Populating procedures...") { + protected org.eclipse.core.runtime.IStatus run( + org.eclipse.core.runtime.IProgressMonitor monitor) { + fileTree = populateDataList(treeViewer); + VizApp.runAsync(new Runnable() { + @Override + public void run() { + treeViewer + .setContentProvider(new ProcedureTreeContentProvider( + fileTree)); + treeViewer + .setLabelProvider(new ProcedureTreeLabelProvider()); + treeViewer.setSorter(new ProcedureTreeSorter()); - treeViewer - .setContentProvider(new ProcedureTreeContentProvider(fileTree)); - treeViewer.setLabelProvider(new ProcedureTreeLabelProvider()); - treeViewer.setSorter(new ProcedureTreeSorter()); + // uncomment following function call to enable the right + // click + // context + // menu + // createContextMenu(); - // uncomment following function call to enable the right click context - // menu - // createContextMenu(); + // it didn't seem to start with null, the string doesn't + // actually mean + // anything in this case + treeViewer.setInput("kickstart"); - // it didn't seem to start with null, the string doesn't actually mean - // anything in this case - treeViewer.setInput("kickstart"); + openUserInTreeViewer(); - openUserInTreeViewer(); - - createExpandComp(textComp); + createExpandComp(textComp); + getShell().setCursor(cursor); + } + }); + return Status.OK_STATUS; + } + }; + job.schedule(); } private void createContextMenu() { diff --git a/cave/com.raytheon.uf.viz.datadelivery/localization/DataDelivery/DataTypeFilter.xml b/cave/com.raytheon.uf.viz.datadelivery/localization/DataDelivery/DataTypeFilter.xml index 4002683720..f9bc49e0a1 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/localization/DataDelivery/DataTypeFilter.xml +++ b/cave/com.raytheon.uf.viz.datadelivery/localization/DataDelivery/DataTypeFilter.xml @@ -6,7 +6,7 @@ Level Parameter - + Data Provider Data Set diff --git a/cave/com.raytheon.uf.viz.datadelivery/localization/help/dataBrowserHelp.xml b/cave/com.raytheon.uf.viz.datadelivery/localization/help/dataBrowserHelp.xml new file mode 100644 index 0000000000..84ca006a67 --- /dev/null +++ b/cave/com.raytheon.uf.viz.datadelivery/localization/help/dataBrowserHelp.xml @@ -0,0 +1,83 @@ + + + Dataset Discovery Browser Help + + + +
+ The Dataset Discovery Browser allows users to find Datasets using a filtering scheme. +
+ + +First is the optional Area filter. Selecting an area only displays datasets that have coverage over the area. Next select and available Data Type. Move the data type to the selected column using the arrows. Next select from the filtering options. Filters include Data Provider, Dataset, Level, and Parameter. Click the arrows to the left of the Filter titles to expand the filter selection sections. After Filters are selected, click Update Results to load the list of Datasets in the table. Select a Dataset and click the Subset... button. Optionally, select Subset information. Enter a Subset Name. Click the Subscribe button to subscribe to the subset. Click the Query button to find details about the subset. + +
+ +
+ File Menu +
+ +
+ +
+ New Configuration... +
+ + Clear the current configuration settings. + +
+ +
+ Load Configuration... +
+ +Load a previously saved configuration file. Select from the Available Configuration Files list and click the Load button to load a configuration file. Use the Preview button to view the XML associated with the configuration file. + +
+ +
+ Save Configuration +
+ +Save the current configuration settings to the most recently saved file name. The first time Save Configuration is accessed, select to save either at the User or Site level and enter a file name. Click the Save button to save the file. Use the Load Configuration menu item to load a saved configuration. + +
+ +
+ Save Configuration As... +
+ +Save the current configuration settings to a named file that may be loaded in the future. In the Save Configuration dialog select to save either at the User or Site level and enter a file name. Click the Save button to save the file. Use the Load Configuration menu item to load a saved configuration. + +
+ +
+ Delete Configuration... +
+ +Delete a saved configuration file. + +
+ +
+ Exit +
+ +Exit the table. + +
+ +
+ Settings Menu +
+ +
+ +
+ Tooltips +
+ + Turn on mouseover tooltips for the controls. + +
+
\ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.datadelivery/localization/help/notificationHelp.xml b/cave/com.raytheon.uf.viz.datadelivery/localization/help/notificationHelp.xml new file mode 100644 index 0000000000..34a8613c2d --- /dev/null +++ b/cave/com.raytheon.uf.viz.datadelivery/localization/help/notificationHelp.xml @@ -0,0 +1,134 @@ + + + Notification Center Help + + + +
+ The Notification Center Table allows a user to view and delete data delivery notifications. +
+ + +
+ +
+ File Menu +
+ +
+ +
+ Set as Default +
+ +Set the current configuration settings to be the default settings for the table. When the table is opened the saved default settings are applied. + +
+ +
+ Load Configuration... +
+ +Load a previously saved configuration file. Select from the Available Configuration Files list and click the Load button to load a configuration file. Use the Preview button to view the XML + associated with the configuration file. + +
+ +
+ Save Configuration +
+ +Save the current configuration settings to the most recently saved file name. The first time Save Configuration is accessed, select to save either at the User or Site level and enter a file name. Click the Save button to save the file. Use the Load Configuration menu item to load a saved configuration. + +
+ +
+ Save Configuration As... +
+ +Save the current configuration settings to a named file that may be loaded in the future. In the Save Configuration dialog select to save either at the User or Site level and enter a file name. Click the Save button to save the file. Use the Load Configuration menu item to load a saved configuration. + +
+ +
+ Delete Configuration... +
+ +Delete a saved configuration file. + +
+ +
+ Exit +
+ +Close the Notification Center. + +
+ +
+ Edit Menu +
+ +
+ +
+ Find... +
+ +Find and highlight items in the table using the Find dialog. The Case Sensitive option allows a user to search text that is capitalization sensitive. The Exclude option allows a user to search the table for items that exclude the entered text. The Case Sensitive and Exclude options may be used in conjunction with another. The Column Selection grouping allows users to search a specific column in the table. After the search criteria has been selected, click the Find Next button to perform the search. The Highlight All button highlights all the rows matching the find criteria. Close the Find dialog using the Close button. + +
+ +
+ Delete by Priority +
+ +Delete all rows in the table having a specific priority. (Note: Notifications only deleted from the user view and not permanently deleted from the database.) + +
+ +
+ Delete Older Than Selected +
+ +Delete all rows in the table having a date in the Time column that is older than the currently highlighted row. (Note: Notifications only deleted from the user view and not permanently deleted from the database.) + +
+ +
+ Delete Notifications +
+ +Delete the currently highlighted row(s) in the table. (Note: Notifications only deleted from the user view and not permanently deleted from the database.) + +
+ +
+ Settings Menu +
+ +
+ +
+ Configure Table... +
+ +The Initial Startup Configuration items are set when the table is opened. Check the Load All Messages check box to display all messages in the table that are contained in the database. Enter a number of messages or hours amount in the Load Last spinner to select the amount of messages or number of hours of messages to display in the table. Set the Initial Sort Column and either Sort Ascending or Sort Descending to sort the table by a specific column upon opening. + +The Display Configuration items refresh the table upon clicking OK. Select the number of Rows Per Page using the selection drop down. Select the image setting for the Priority table column using the radio buttons. Select to make columns hidden or visible using the arrows provided. After making selections, click the OK button to configure the table. (Note: Unless the configuration is set to the default or saved, changes will be lost when the table is closed.) + +
+ +
+ Filter Table... +
+ +A user may filter the table by user, by subscription or by priority. In the Filter by User section, the list of available user names are in the Available Users column. If users are moved to the Selected Users list, the corresponding columns containing those user names will be displayed in the Notification Table. Use the arrows to move users back and forth from the Available Users list to the Selected Users list. (Note: User names are not duplicated and appear only once either in the Available or Selected lists.) The Always include my notifications check box may be used to keep the currently logged in user in the Selected Users column. + +In the Filter by Subscription section, the list of available subscription names are in the Available Subscriptions column. If subscriptions are moved to the Selected Subscriptions list the corresponding columns containing those subscription names will be displayed in the Notification Table. Use the arrows to move subscriptions back and forth from the Available Subscriptions list to the Selected Subscriptions list. (Note: Subscription names are not duplicated and appear only once either in the Available or Selected lists.) + +In the Filter by Priority section, select which columns containing specific priorities to display using the checkboxes. + +
+
diff --git a/cave/com.raytheon.uf.viz.datadelivery/localization/help/subscriptionApprovalHelp.xml b/cave/com.raytheon.uf.viz.datadelivery/localization/help/subscriptionApprovalHelp.xml new file mode 100644 index 0000000000..ea3491415c --- /dev/null +++ b/cave/com.raytheon.uf.viz.datadelivery/localization/help/subscriptionApprovalHelp.xml @@ -0,0 +1,64 @@ + + + Subscription Approval Help + + + +
+ The Subscription Approval Dialog allows an authorized user to approve or deny subscriptions. +
+ + + +
+ +
+ File Menu +
+ +
+ +
+ Exit +
+ + Close the dialog. + +
+ +
+ View Menu +
+ +
+ +
+ Details... +
+ + View the details of the highlighted subscription. + +
+ +
+ Action Menu +
+ +
+ +
+ Approve Selected +
+ + Approve the highlighted subscription. + +
+ +
+ Deny Selected +
+ + Deny the highlighted subscription + +
+
\ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.datadelivery/localization/help/subscriptionManagerHelp.xml b/cave/com.raytheon.uf.viz.datadelivery/localization/help/subscriptionManagerHelp.xml new file mode 100644 index 0000000000..2d312fbf6d --- /dev/null +++ b/cave/com.raytheon.uf.viz.datadelivery/localization/help/subscriptionManagerHelp.xml @@ -0,0 +1,137 @@ + + + Subscription Manager Help + + + +
+ The Subscription Manager Table allows a user to add, edit, copy, view, and delete data delivery subscriptions. +
+ + +First is the optional Area filter. Selecting an area only displays datasets that have coverage over the area. Next select and available Data Type. Move the data type to the selected column using the arrows. Next select from the filtering options. Filters include Data Provider, Dataset, Level, and Parameter. Click the arrows to the left of the Filter titles to expand the filter selection sections. After Filters are selected, click Update Results to load the list of Datasets in the table. Select a Dataset and click the Subset... button. Optionally, select Subset information. Enter a Subset Name. Click the Subscribe button to subscribe to the subset. Click the Query button to find details about the subset. + +
+ +
+ File Menu +
+ +
+ +
+ New Subscription... +
+ + The New Subscription menu option opens the Dataset Discovery Browser. + +
+ +
+ New Group... +
+ + The New Group menu option allows the user to create a new subscription group. First enter a group name. Next select the Subscription Duration, Active Period, and Areal Coverage. Finally select which subscriptions to add to the new group. + +
+ +
+ Refresh Table +
+ + Refresh the table data. + +
+ +
+ Approve Pending Subscriptions... +
+ + Opens the Subscription Approval dialog. + +
+ +
+ Exit +
+ + Close the dialog. + +
+ +
+ Edit Menu +
+ +
+ +
+ Edit Subscription... +
+ +Highlight a row in the table to edit. Modify the Subscription Delivery Options, the Subscription Duration, the Subscription Active Period, the Subscription Priority or the additional Subscription Information. + +Subscription Duration sets the start and expiration times for subscription delivery. Use the No Expiration radio button to continue to receive the subscription. + +The Subscription Active Period may be used to select a specified time range for the subscription to be active. (Note: The active period does not include the year.) The Subscription Priority sets the order of subscription fulfillment and may be set to High (1), Default (2), or Low (3). + +The Subscription Information allows the Description to be modified. The Subscription Name may not be modified. + +Click OK to perform the edit. + +
+ +
+ Copy Subscription... +
+ + Highlight a row in the table to copy. Enter a New Subscription Name. Click OK to perform the copy. + +
+ +
+ Delete Subscription... +
+ + Highlight a row(s) in the table to delete. Click Yes to perform the deletion. + +
+ +
+ Edit Group... +
+ + Edit the group settings. Select a group to edit, change the settings, click OK to save the edit. + +
+ +
+ Delete Group... +
+ + Select a group to delete and click OK to delete the group. + +
+ +
+ Settings Menu +
+ +
+ +
+ Configure Table... +
+ +The Table Column Configuration Settings allow a user to hide and make visible table columns. The list of Hidden Columns is located on the left and the Visible Columns list is located on the right. If columns are moved to the Visible Columns list, the corresponding columns will be displayed in the Notification Table. Use the right and left arrows to move column names back and forth from the Hidden Columns list to the Visible Columns list. Use the up and down arrows to change the order of the visible columns as seen in the table. (Note: Column names are not duplicated and appear only once either in the Hidden or Visible lists.) After making selections, click the OK button to configure the table. (Note: Unless the configuration is set to the default or saved, changes will be lost when the table is closed.) + +
+ +
+ Tooltips +
+ +Turns on the mouseover tooltips for the dialog's controls. + +
+
\ No newline at end of file diff --git a/cave/com.raytheon.uf.viz.datadelivery/res/spring/datadelivery-handlers.xml b/cave/com.raytheon.uf.viz.datadelivery/res/spring/datadelivery-handlers.xml index 4d65892ed8..f07a2434dc 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/res/spring/datadelivery-handlers.xml +++ b/cave/com.raytheon.uf.viz.datadelivery/res/spring/datadelivery-handlers.xml @@ -1,7 +1,7 @@ + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd + http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd"> + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd + http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd"> diff --git a/cave/com.raytheon.uf.viz.datadelivery/res/spring/datadelivery.xml b/cave/com.raytheon.uf.viz.datadelivery/res/spring/datadelivery.xml index 3a9ccee31e..85bf5f83e4 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/res/spring/datadelivery.xml +++ b/cave/com.raytheon.uf.viz.datadelivery/res/spring/datadelivery.xml @@ -2,10 +2,10 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util" xmlns:context="http://www.springframework.org/schema/context" - xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd - http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd + xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd + http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/util - http://www.springframework.org/schema/util/spring-util-2.5.xsd"> + http://www.springframework.org/schema/util/spring-util-3.1.xsd"> diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/actions/SubscriptionManagerAction.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/actions/SubscriptionManagerAction.java index 4c88e80f9f..c0eefec0dd 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/actions/SubscriptionManagerAction.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/actions/SubscriptionManagerAction.java @@ -21,7 +21,6 @@ package com.raytheon.uf.viz.datadelivery.actions; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; -import org.eclipse.core.commands.ExecutionException; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.PlatformUI; @@ -33,7 +32,9 @@ import com.raytheon.uf.common.status.UFStatus.Priority; import com.raytheon.uf.viz.core.auth.UserController; import com.raytheon.uf.viz.core.exception.VizException; import com.raytheon.uf.viz.datadelivery.services.DataDeliveryServices; +import com.raytheon.uf.viz.datadelivery.subscription.ISubscriptionManagerFilter; import com.raytheon.uf.viz.datadelivery.subscription.SubscriptionManagerDlg; +import com.raytheon.uf.viz.datadelivery.subscription.SubscriptionManagerFilters; /** * Subscription Manager Dialog Action class. @@ -46,6 +47,7 @@ import com.raytheon.uf.viz.datadelivery.subscription.SubscriptionManagerDlg; * ------------ ---------- ----------- -------------------------- * Jan 10, 2012 mpduff Initial creation * Oct 03, 2012 1241 djohnson Use {@link DataDeliveryPermission}. + * May 28, 2013 1650 djohnson Allow using filters for the Subscription Manager Dialog. * * * @@ -54,6 +56,7 @@ import com.raytheon.uf.viz.datadelivery.subscription.SubscriptionManagerDlg; */ public class SubscriptionManagerAction extends AbstractHandler { + /** Status Handler */ private final IUFStatusHandler statusHandler = UFStatus .getHandler(SubscriptionManagerAction.class); @@ -64,8 +67,24 @@ public class SubscriptionManagerAction extends AbstractHandler { /** Permission String */ private final DataDeliveryPermission permission = DataDeliveryPermission.SUBSCRIPTION_VIEW; + /** + * Constructor. + */ + public SubscriptionManagerAction() { + } + @Override - public Object execute(ExecutionEvent arg0) throws ExecutionException { + public Object execute(ExecutionEvent arg0) { + return loadSubscriptionManager(SubscriptionManagerFilters.getAll()); + } + + /** + * Load the SubscriptionManager dialog with the specified filter. + * + * @param filter + * the filter + */ + public Object loadSubscriptionManager(ISubscriptionManagerFilter filter) { try { // check if user is authorized IUser user = UserController.getUserObject(); @@ -78,7 +97,7 @@ public class SubscriptionManagerAction extends AbstractHandler { if ((dlg == null) || (dlg.isDisposed() == true)) { Shell shell = PlatformUI.getWorkbench() .getActiveWorkbenchWindow().getShell(); - dlg = new SubscriptionManagerDlg(shell); + dlg = new SubscriptionManagerDlg(shell, filter); dlg.open(); } else { dlg.bringToTop(); diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/browser/DataBrowserDlg.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/browser/DataBrowserDlg.java index 28ca1fb44e..6c36cabbb1 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/browser/DataBrowserDlg.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/browser/DataBrowserDlg.java @@ -77,6 +77,7 @@ import com.raytheon.uf.viz.datadelivery.filter.MetaDataManager; import com.raytheon.uf.viz.datadelivery.filter.config.FilterManager; import com.raytheon.uf.viz.datadelivery.filter.config.xml.FilterSettingsXML; import com.raytheon.uf.viz.datadelivery.filter.config.xml.FilterTypeXML; +import com.raytheon.uf.viz.datadelivery.help.HelpManager; import com.raytheon.uf.viz.datadelivery.services.DataDeliveryServices; import com.raytheon.uf.viz.datadelivery.subscription.subset.SubsetManagerDlg; import com.raytheon.uf.viz.datadelivery.utils.DataDeliveryGUIUtils; @@ -115,6 +116,9 @@ import com.vividsolutions.jts.geom.Coordinate; * Jan 08, 2012 1436 bgonzale Fixed area text box display update check. * Jan 14, 2012 1437 bgonzale Clear filters when creating a new configuration. * May 15, 2013 1040 mpduff Put DataDeliveryGUIUtils.markNotBusyInUIThread in finally block. + * Jun 04, 2013 223 mpduff Add data type to filters. + * Jun 05, 2013 1800 mpduff Move the area filter below the data type selection. + * Jun 06, 2013 2030 mpduff Updates to help. * * * @@ -128,6 +132,9 @@ public class DataBrowserDlg extends CaveSWTDialog implements IDataTableUpdate, private final IUFStatusHandler statusHandler = UFStatus .getHandler(DataBrowserDlg.class); + /** File containing help text */ + private final String DATA_BROWSER_HELP_FILE = "help/dataBrowserHelp.xml"; + /** Window Title string. */ private final String WINDOW_TITLE = "Dataset Discovery Browser"; @@ -139,9 +146,6 @@ public class DataBrowserDlg extends CaveSWTDialog implements IDataTableUpdate, private static final String DEFAULT_CONFIG = FileUtil.join(CONFIG_PATH, "DefaultBrowserConfig.xml"); - /** Help Dialog */ - private final DataBrowserHelpDlg help = null; - /** Filter expand bar. */ private FilterExpandBar filterExpandBar; @@ -263,8 +267,8 @@ public class DataBrowserDlg extends CaveSWTDialog implements IDataTableUpdate, protected void initializeComponents(Shell shell) { createMenus(); - createAreaControls(); createDataTypeControls(); + createAreaControls(); createSashForm(); createRetSubsControl(); @@ -713,14 +717,14 @@ public class DataBrowserDlg extends CaveSWTDialog implements IDataTableUpdate, * Handle the help display dialog. */ private void handleHelp() { - - if (help == null || help.isDisposed()) { - DataBrowserHelpDlg help = new DataBrowserHelpDlg(shell); - help.open(); - } else { - help.bringToTop(); + try { + HelpManager.getInstance().displayHelpDialog(getShell(), + DATA_BROWSER_HELP_FILE); + } catch (Exception e) { + statusHandler.handle(Priority.ERROR, + "Error loading Help Text file: " + DATA_BROWSER_HELP_FILE, + e); } - } /** @@ -1054,6 +1058,12 @@ public class DataBrowserDlg extends CaveSWTDialog implements IDataTableUpdate, // Get selected filter settings xml = new FilterSettingsXML(); filterExpandBar.populateFilterSettingsXml(xml); + + String[] dataTypes = this.dataTypesDualList.getSelectedListItems(); + for (String type : dataTypes) { + xml.addDataSetType(type); + } + final List matchingDataSets = new ArrayList(); final Shell jobParent = this.getShell(); diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/browser/DataBrowserHelpDlg.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/browser/DataBrowserHelpDlg.java deleted file mode 100644 index d6231f6d57..0000000000 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/browser/DataBrowserHelpDlg.java +++ /dev/null @@ -1,89 +0,0 @@ -package com.raytheon.uf.viz.datadelivery.browser; - -import org.eclipse.swt.widgets.Shell; - -import com.raytheon.uf.viz.datadelivery.help.DataDeliveryHelp; - -/** - * Help dialog for the Data Discover Browser. - * - *
- * 
- * SOFTWARE HISTORY
- * 
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * May 21, 2012   645      jpiatt     Initial creation.
- * 
- * 
- * - * @author jpiatt - * @version 1.0 - */ - -public class DataBrowserHelpDlg extends DataDeliveryHelp { - - /** - * Constructor. - * @param parentShell - * Parent shell. - */ - public DataBrowserHelpDlg(Shell parentShell) { - - this.parentShell = parentShell; - this.helpText = getHelpText(); - - } - - /** - * Get the Help Text. - * - * @return String - * Help Text. - */ - private String getHelpText() { - - String helpText = "Dataset Discovery Browser Help" + - "The Dataset Discovery Browser allows a user to find Datasets using " + - "filtering options.
First, select an Area for the Areal Coverage. Optionally, use" + - "the Set Area to select an Area. Next, select an available Data Type. Move the data type to " + - "the selected column using the arrows. Next, select from the filtering options. Filters " + - "include Data Provider, Data Set, Level or Parameter. Click the arrows to the left of the " + - "Filter titles to expand the filter selection sections. After Filters are selected, click " + - "Update Results to load the list of Datasets in the table. Select a Dataset and click the " + - "Subset... button. Optionally, select Subset information. Enter a Subset Name. Click " + - "the Subscribe button to subscribe to the subset. Click the Query button " + - "to find details about the subset." + - "
" + - "
" + - "
File
" + - "
New Configuration
" + - " Clear the current configuration settings.
" + - " Load Configuration...
" + - " Load a previously saved configuration file. Select from the Available " + - " Configuration Files list and click the Load button to load a configuration " + - " file. Use the Preview button to view the XML associated with the " + - " configuration file.
" + - " Save Configuration
" + - " Save the current configuration settings to the most recently " + - " saved file name. The first time Save Configuration is accessed, " + - " select to save either at the User or Site level and enter a file name. " + - " Click the Save button to save the file. Use the Load Configuration " + - " menu item to load a saved configuration.
" + - " Save Configuration As...
" + - " Save the current configuration settings to a named file " + - " that may be loaded in the future. In the Save Configuration dialog " + - " select to save either at the User or Site level and enter a file name. " + - " Click the Save button to save the file. Use the Load Configuration " + - " menu item to load a saved configuration.
" + - " Delete Configuration...
" + - " Delete a saved configuration file.
" + - " Exit
" + - " Exit the table.

" + - "
" + - ""; - - return helpText; - - } -} diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/common/ui/AreaComp.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/common/ui/AreaComp.java index b6c2381089..051bf12ab9 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/common/ui/AreaComp.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/common/ui/AreaComp.java @@ -68,11 +68,11 @@ import com.vividsolutions.jts.geom.Coordinate; /** * This is a common composite that is used to hold the area controls. - * + * *
- *
+ * 
  * SOFTWARE HISTORY
- *
+ * 
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
  * Feb 28, 2012            lvenable     Initial creation.
@@ -90,9 +90,10 @@ import com.vividsolutions.jts.geom.Coordinate;
  * Dec 10, 2012  1259      bsteffen     Switch Data Delivery from LatLon to referenced envelopes.
  * Dec 11, 2012  1264      mpduff       Fix validaiton of lat/lon text fields.
  * Mar 21, 2013  1638      mschenke     Changed map scales not tied to d2d
- *
+ * Jun 14, 2013  2064      mpduff       Reset controls on load.
+ * 
  * 
- * + * * @author lvenable * @version 1.0 */ @@ -187,7 +188,7 @@ public class AreaComp extends Composite implements ISubset { /** * Constructor. - * + * * @param parent * Parent composite. * @param groupTxt @@ -237,6 +238,7 @@ public class AreaComp extends Composite implements ISubset { setupData(); createControls(); + updateRegionControls(); if (regionRdo.getSelection()) { // Try to find the smallest region that intersects, assum regions // are listed largest to smallest. @@ -293,7 +295,7 @@ public class AreaComp extends Composite implements ISubset { /** * Create the bound controls. - * + * * @param group * Group container. */ @@ -361,7 +363,7 @@ public class AreaComp extends Composite implements ISubset { /** * Create the region and bounding box controls. - * + * * @param group * Group container. */ @@ -486,7 +488,7 @@ public class AreaComp extends Composite implements ISubset { /** * Add a separator line to the display. - * + * * @param parentComp * Parent component. */ @@ -502,7 +504,7 @@ public class AreaComp extends Composite implements ISubset { /** * Enable/Disable the region and bounding box controls. The bounding box * control will always be the disabled if the region controls are enabled. - * + * */ public void updateRegionControls() { enableCustomControls(manualRdo.getSelection()); @@ -513,7 +515,7 @@ public class AreaComp extends Composite implements ISubset { /** * Set controls enabled based on flag. - * + * * @param flag * true if controls should be enabled */ @@ -524,7 +526,7 @@ public class AreaComp extends Composite implements ISubset { /** * Set text controls enabled based on flag. - * + * * @param flag * true if text controls should be enabled */ @@ -544,7 +546,7 @@ public class AreaComp extends Composite implements ISubset { /** * Get the text background based on if the control is enabled or not - * + * * @param enabled * enabled flag */ @@ -560,7 +562,7 @@ public class AreaComp extends Composite implements ISubset { /** * Enable the regions control based on the flag. - * + * * @param flag * enabled state of the controls */ @@ -575,7 +577,7 @@ public class AreaComp extends Composite implements ISubset { /** * Enable the bounding box controls base on the flag. - * + * * @param flag * enabled state of the controls */ @@ -585,7 +587,7 @@ public class AreaComp extends Composite implements ISubset { /** * Enable all controls using flag. - * + * * @param flag * on/off toggle for controls. */ @@ -753,7 +755,7 @@ public class AreaComp extends Composite implements ISubset { /** * Get the user Regions. - * + * * @return array of user regions */ private String[] getUserRegions() { @@ -852,7 +854,7 @@ public class AreaComp extends Composite implements ISubset { /** * Get a double from text. - * + * * @param text * The double String * @return double, Double.NaN if unable to parse @@ -879,6 +881,10 @@ public class AreaComp extends Composite implements ISubset { } } + /** + * {@inheritDoc} + */ + @Override public void updateBounds(ReferencedEnvelope envelope) { Coordinate ul = EnvelopeUtils.getUpperLeftLatLon(envelope); Coordinate lr = EnvelopeUtils.getLowerRightLatLon(envelope); @@ -895,7 +901,7 @@ public class AreaComp extends Composite implements ISubset { /* * (non-Javadoc) - * + * * @see com.raytheon.uf.viz.datadelivery.subscription.subset.ISubset# * updateSelectionState(boolean, java.lang.String) */ @@ -906,7 +912,7 @@ public class AreaComp extends Composite implements ISubset { /** * Select the custom radio button - * + * * @param regionName */ public void setRegion(String regionName) { @@ -941,12 +947,11 @@ public class AreaComp extends Composite implements ISubset { } index++; } - } /** * Select the custom radio button. - * + * * @return region name */ public String getRegionName() { @@ -980,7 +985,7 @@ public class AreaComp extends Composite implements ISubset { /** * Switch to "My Regions" as the active selection and select the provided * region name. - * + * * @param regionName */ public void showMyRegions(String regionName) { @@ -1009,7 +1014,7 @@ public class AreaComp extends Composite implements ISubset { /** * @return the envelopeValid */ - public boolean isEnvelopeValid() { + public boolean isEnvelopeValid() { return envelopeValid; } @@ -1033,6 +1038,6 @@ public class AreaComp extends Composite implements ISubset { validateBoundsText(); } - } - + } + } diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/common/ui/LoadSaveConfigDlg.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/common/ui/LoadSaveConfigDlg.java index 578ba96dcb..524336b5a8 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/common/ui/LoadSaveConfigDlg.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/common/ui/LoadSaveConfigDlg.java @@ -62,6 +62,7 @@ import com.raytheon.uf.viz.datadelivery.filter.config.xml.FilterTypeXML; import com.raytheon.uf.viz.datadelivery.notification.xml.NotificationConfigXML; import com.raytheon.uf.viz.datadelivery.notification.xml.NotificationFilterXML; import com.raytheon.uf.viz.datadelivery.subscription.subset.xml.DateRangeTimeXML; +import com.raytheon.uf.viz.datadelivery.subscription.subset.xml.PointTimeXML; import com.raytheon.uf.viz.datadelivery.subscription.subset.xml.SpecificDateTimeXML; import com.raytheon.uf.viz.datadelivery.subscription.subset.xml.SubsetXML; import com.raytheon.uf.viz.datadelivery.subscription.subset.xml.TimeXML; @@ -84,6 +85,7 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog; * Jun 19, 2012 717 jpiatt Save action update. * Aug 22, 2012 0743 djohnson Add new TimeXML sub-classes. * Apr 25, 2013 1820 mpduff Implement deletion of config file. + * Jun 04, 2013 223 mpduff Refactor method rename and add new class to JaxB context. * * * @@ -635,7 +637,7 @@ public class LoadSaveConfigDlg extends CaveSWTDialog { NotificationFilterXML.class, FilterSettingsXML.class, FilterTypeXML.class, SubscriptionManagerConfigXML.class, SubsetXML.class, TimeXML.class, SpecificDateTimeXML.class, - DateRangeTimeXML.class, VerticalXML.class }; + DateRangeTimeXML.class, VerticalXML.class, PointTimeXML.class }; try { jax = JAXBContext.newInstance(classes); @@ -822,7 +824,7 @@ public class LoadSaveConfigDlg extends CaveSWTDialog { if (obj instanceof IDisplayXml) { IDisplayXml dispXml = (IDisplayXml) obj; - previewTxt.setText(dispXml.getDisplayXmlString()); + previewTxt.setText(dispXml.getPreviewString()); } else { this.marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/common/ui/PriorityComp.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/common/ui/PriorityComp.java index 180afac3f5..19bcf377b7 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/common/ui/PriorityComp.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/common/ui/PriorityComp.java @@ -46,6 +46,7 @@ import com.raytheon.uf.common.datadelivery.registry.Subscription.SubscriptionPri * Aug 21, 2012 712 mpduff Default to Default, and allow for setting the combo box. * Jan 04, 2013 1420 mpduff Add latency. * Jan 25, 2013 1528 djohnson Use priority enum instead of raw integers. + * Jun 04, 2013 223 mpduff Changes for Point Data. * * * @@ -65,6 +66,10 @@ public class PriorityComp extends Composite { /** The priority value */ private SubscriptionPriority priority; + private final boolean readOnlyLatency; + + private Label latencyLabel; + /** * Constructor. * @@ -74,10 +79,11 @@ public class PriorityComp extends Composite { * @param priority */ public PriorityComp(Composite parent, int latency, - SubscriptionPriority priority) { + SubscriptionPriority priority, boolean readOnlyLatency) { super(parent, SWT.NONE); this.latency = latency; this.priority = priority; + this.readOnlyLatency = readOnlyLatency; init(); } @@ -151,12 +157,21 @@ public class PriorityComp extends Composite { Label latencyLbl = new Label(latencyComp, SWT.NONE); latencyLbl.setText("Latency (Minutes):"); - latencyText = new Text(latencyComp, SWT.BORDER); - latencyText.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, - false)); - latencyText - .setToolTipText("Time in minutes allotted for a subscription to download"); - latencyText.setText(String.valueOf(this.latency)); + if (readOnlyLatency) { + latencyLabel = new Label(latencyComp, SWT.BORDER); + latencyLabel.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, + true, false)); + latencyLabel + .setToolTipText("Point Data's latency is the retrieval interval."); + latencyLabel.setText(String.valueOf(this.latency)); + } else { + latencyText = new Text(latencyComp, SWT.BORDER); + latencyText.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, + false)); + latencyText + .setToolTipText("Time in minutes allotted for a subscription to download"); + latencyText.setText(String.valueOf(this.latency)); + } } /** @@ -185,7 +200,13 @@ public class PriorityComp extends Composite { * entry entered */ public int getLatencyValue() { - String latency = latencyText.getText().trim(); + String latency; + if (latencyText != null) { + latency = latencyText.getText().trim(); + } else { + latency = latencyLabel.getText(); + } + int intLatency; try { intLatency = Integer.parseInt(latency); diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/common/ui/SubscriptionViewer.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/common/ui/SubscriptionViewer.java index ade517177d..b2e70ca470 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/common/ui/SubscriptionViewer.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/common/ui/SubscriptionViewer.java @@ -33,6 +33,8 @@ import org.eclipse.swt.widgets.Layout; import org.eclipse.swt.widgets.Shell; import com.raytheon.uf.viz.datadelivery.subscription.ISubscriptionAction; +import com.raytheon.uf.viz.datadelivery.subscription.ISubscriptionManagerFilter; +import com.raytheon.uf.viz.datadelivery.subscription.SubscriptionManagerFilters; import com.raytheon.uf.viz.datadelivery.subscription.SubscriptionTableComp; import com.raytheon.uf.viz.datadelivery.subscription.SubscriptionTableComp.SubscriptionType; import com.raytheon.uf.viz.datadelivery.utils.DataDeliveryUtils.TABLE_TYPE; @@ -53,6 +55,7 @@ import com.raytheon.uf.viz.datadelivery.utils.DataDeliveryUtils.TABLE_TYPE; * Dec 03, 2012 1269 mpduff Change to take a list of subscriptions for the view mode. * Dec 10, 2012 1300 bgonzale Table filtering by dataset and provider. * May 23, 2012 2020 mpduff Implement method. + * May 28, 2013 1650 djohnson Filters now control what subscriptions are shown. * * * @author mpduff @@ -179,16 +182,16 @@ public class SubscriptionViewer extends AbstractViewDlg implements tableConfig.setTableStyle(SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.MULTI | SWT.FULL_SELECTION); tableConfig.setTableHeight(200); - tableComp = new SubscriptionTableComp(shell, tableConfig, this, - SubscriptionType.VIEWER); - if (isTableFilteredByDatasetAndProvider()) { - tableComp.populateActiveFilteredDataByDataSetAndProvider( - datasetName, providerName); - } else { - tableComp.setSubscriptionNameList(this.subscriptionNameList); - tableComp.populateData(); - } + ISubscriptionManagerFilter filter = (isTableFilteredByDatasetAndProvider()) ? SubscriptionManagerFilters + .getByProviderAndDataSet(providerName, datasetName) : +SubscriptionManagerFilters + .getByNames(this.subscriptionNameList); + + tableComp = new SubscriptionTableComp(shell, tableConfig, this, + SubscriptionType.VIEWER, filter); + + tableComp.populateData(); tableComp.populateTable(); } diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/common/ui/UserSelectComp.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/common/ui/UserSelectComp.java index 3ba53d7ba4..df617e40b6 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/common/ui/UserSelectComp.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/common/ui/UserSelectComp.java @@ -93,6 +93,8 @@ import com.raytheon.viz.ui.widgets.duallist.IUpdate; * Jan 02, 2013 1441 djohnson Access GroupDefinitionManager in a static fashion. * Apr 08, 2013 1826 djohnson Remove unused code, delivery options. * May 15, 2013 1040 mpduff OfficeID is now a list so need to add it rather than set it. + * May 23, 2013 1650 djohnson Fix creation of new GroupDefinitions. + * May 28, 2013 1650 djohnson More information when failing to schedule subscriptions. * * * @author jpiatt @@ -359,6 +361,10 @@ public class UserSelectComp extends Composite implements IUpdate, IDisplay, // Get Group Definition GroupDefinition groupDefinition = GroupDefinitionManager .getGroup(groupName); + if (groupDefinition == null) { + groupDefinition = new GroupDefinition(); + groupDefinition.setGroupName(groupName); + } for (Subscription subscription : groupSubscriptions) { @@ -499,15 +505,20 @@ public class UserSelectComp extends Composite implements IUpdate, IDisplay, public String getOptionDisplayText(ForceApplyPromptResponse option, int requiredLatency, Subscription subscription, Set wouldBeUnscheduledSubscriptions) { + final boolean singleSubscription = wouldBeUnscheduledSubscriptions + .size() == 1; switch (option) { case CANCEL: return "Do not update the group definition."; case FORCE_APPLY: - if (wouldBeUnscheduledSubscriptions.size() == 1) { + if (singleSubscription) { return "Update the group definition and unschedule " + wouldBeUnscheduledSubscriptions.iterator().next(); } return "Update the group definition and unschedule the subscriptions"; + case EDIT_SUBSCRIPTIONS: + return "Edit the " + + ((singleSubscription) ? "subscription" : "subscriptions"); case INCREASE_LATENCY: // Signifies it should not be an option return null; diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/common/xml/AreaXML.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/common/xml/AreaXML.java index 4c56283b12..d40039ebc7 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/common/xml/AreaXML.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/common/xml/AreaXML.java @@ -46,6 +46,7 @@ import com.vividsolutions.jts.geom.Coordinate; * Mar 27, 2012 mpduff Initial creation. * Jun 7, 2012 684 jpiatt Added region name. * Dec 10, 2012 1259 bsteffen Switch Data Delivery from LatLon to referenced envelopes. + * Jun 04, 2013 223 mpduff Changed method name. * * * @@ -101,7 +102,7 @@ public class AreaXML implements IDisplayXml { * () */ @Override - public String getDisplayXmlString() { + public String getPreviewString() { StringBuilder sb = new StringBuilder(); sb.append("Type: Area\n"); diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/common/xml/IDisplayXml.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/common/xml/IDisplayXml.java index 2a9cbbfa48..20b147d620 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/common/xml/IDisplayXml.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/common/xml/IDisplayXml.java @@ -29,6 +29,7 @@ package com.raytheon.uf.viz.datadelivery.common.xml; * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Feb 29, 2012 lvenable Initial creation + * Jun 04, 2013 223 mpduff Change method name to getPreviewString * * * @@ -37,5 +38,10 @@ package com.raytheon.uf.viz.datadelivery.common.xml; */ public interface IDisplayXml { - String getDisplayXmlString(); + /** + * Get the xml contents in a formatted string for display. + * + * @return the formatted string + */ + String getPreviewString(); } diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/filter/MetaDataManager.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/filter/MetaDataManager.java index 51cd728996..d8036611bd 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/filter/MetaDataManager.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/filter/MetaDataManager.java @@ -37,7 +37,7 @@ import com.raytheon.uf.common.datadelivery.registry.DataLevelType.LevelType; import com.raytheon.uf.common.datadelivery.registry.DataSet; import com.raytheon.uf.common.datadelivery.registry.GriddedDataSet; import com.raytheon.uf.common.datadelivery.registry.Provider; -import com.raytheon.uf.common.datadelivery.registry.Provider.ProviderType; +import com.raytheon.uf.common.datadelivery.registry.ProviderType; import com.raytheon.uf.common.datadelivery.registry.handlers.DataDeliveryHandlers; import com.raytheon.uf.common.registry.handler.RegistryHandlerException; import com.raytheon.uf.common.status.IUFStatusHandler; @@ -67,6 +67,7 @@ import com.raytheon.uf.viz.datadelivery.filter.config.xml.FilterTypeXML; * Oct 05, 2012 1241 djohnson Replace RegistryManager calls with registry handler calls. * Nov 19, 2012 1166 djohnson Clean up JAXB representation of registry objects. * Dec 10, 2012 1259 bsteffen Switch Data Delivery from LatLon to referenced envelopes. + * Jun 04, 2013 223 mpduff Add data set type to filter. * * * @@ -170,7 +171,7 @@ public class MetaDataManager { .getAll()) { for (ProviderType type : provider.getProviderType()) { - typeSet.add(type.toString()); + typeSet.add(type.getDataType().toString()); } } } catch (RegistryHandlerException e) { @@ -291,10 +292,13 @@ public class MetaDataManager { } } + // Add data set types + List dataSetTypes = xml.getDataSetTypes(); + try { filteredDataSets.addAll(DataDeliveryHandlers.getDataSetHandler() .getByFilters(providers, dataSetNames, levels, - parameterNames, envelope)); + parameterNames, dataSetTypes, envelope)); } catch (RegistryHandlerException e) { statusHandler.handle(Priority.PROBLEM, "Unable to retrieve the filtered datasets.", e); diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/filter/config/xml/FilterSettingsXML.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/filter/config/xml/FilterSettingsXML.java index c2a428ceab..0c4e4ef25d 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/filter/config/xml/FilterSettingsXML.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/filter/config/xml/FilterSettingsXML.java @@ -20,6 +20,7 @@ package com.raytheon.uf.viz.datadelivery.filter.config.xml; import java.util.ArrayList; +import java.util.List; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; @@ -39,7 +40,8 @@ import com.raytheon.uf.viz.datadelivery.common.xml.IDisplayXml; * * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * Feb 27, 2012 mpduff Initial creation + * Feb 27, 2012 mpduff Initial creation. + * Jun 04, 2012 223 mpduff Add data set type and refactor method name change. * * * @@ -51,10 +53,13 @@ import com.raytheon.uf.viz.datadelivery.common.xml.IDisplayXml; public class FilterSettingsXML implements IDisplayXml { @XmlElements({ @XmlElement(name = "Filter", type = FilterTypeXML.class) }) protected ArrayList filterTypeList = new ArrayList(); - + @XmlElement(name = "area", type = AreaXML.class) protected AreaXML area; + @XmlElements({ @XmlElement(name = "DataSetType", type = String.class) }) + protected List dataSetTypes = new ArrayList(); + /** * @return the filterTypeList */ @@ -87,17 +92,17 @@ public class FilterSettingsXML implements IDisplayXml { * () */ @Override - public String getDisplayXmlString() { + public String getPreviewString() { final String newline = "\n"; StringBuilder sb = new StringBuilder(); - + for (FilterTypeXML ftx : filterTypeList) { - sb.append(ftx.getDisplayXmlString()); + sb.append(ftx.getPreviewString()); sb.append(newline); } - + if (area != null) { - sb.append(area.getDisplayXmlString()).append(newline); + sb.append(area.getPreviewString()).append(newline); } return sb.toString(); @@ -111,9 +116,33 @@ public class FilterSettingsXML implements IDisplayXml { } /** - * @param area the area to set + * @param area + * the area to set */ public void setArea(AreaXML area) { this.area = area; } + + /** + * @return the dataSetTypes + */ + public List getDataSetTypes() { + return dataSetTypes; + } + + /** + * @param dataSetTypes + * the dataSetTypes to set + */ + public void setDataSetTypes(List dataSetTypes) { + this.dataSetTypes = dataSetTypes; + } + + /** + * @param type + * the type to add + */ + public void addDataSetType(String type) { + this.dataSetTypes.add(type); + } } diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/filter/config/xml/FilterTypeXML.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/filter/config/xml/FilterTypeXML.java index 9db583d7a4..479e3e5cc8 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/filter/config/xml/FilterTypeXML.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/filter/config/xml/FilterTypeXML.java @@ -38,7 +38,8 @@ import com.raytheon.uf.viz.datadelivery.common.xml.IDisplayXml; * * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- - * Jan 30, 2012 mpduff Initial creation + * Jan 30, 2012 mpduff Initial creation. + * Jun 04, 2013 mpduff Changed method name. * * * @@ -100,7 +101,7 @@ public class FilterTypeXML implements IDisplayXml { * () */ @Override - public String getDisplayXmlString() { + public String getPreviewString() { StringBuilder sb = new StringBuilder(); sb.append("Type: ").append(this.filterType).append("\n"); diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/help/DataDeliveryHelp.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/help/DataDeliveryHelp.java deleted file mode 100644 index 7d1dabf7af..0000000000 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/help/DataDeliveryHelp.java +++ /dev/null @@ -1,103 +0,0 @@ -package com.raytheon.uf.viz.datadelivery.help; - -import org.eclipse.swt.SWT; -import org.eclipse.swt.SWTError; -import org.eclipse.swt.browser.Browser; -import org.eclipse.swt.layout.FillLayout; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.Shell; - -/** - * Find dialog for the Notification Table. - * - *
- * 
- * SOFTWARE HISTORY
- * 
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * May 18, 2012   645      jpiatt     Initial creation.
- * 
- * 
- * - * @author jpiatt - * @version 1.0 - */ - -public abstract class DataDeliveryHelp { - - /** Parent shell */ - protected Shell parentShell; - - /** Browser object */ - protected Browser browser; - - /** Help Text */ - protected String helpText; - - /** Parent shell. */ - Shell shell; - - /** - * Open the browser to display the help text. - */ - public void open() { - - Display display = parentShell.getDisplay(); - shell = new Shell(display); - shell.setLayout(new FillLayout()); - Browser browser; - try { - browser = new Browser(shell, SWT.NONE); - } catch (SWTError e) { - System.out.println("Could not instantiate Browser: " + e.getMessage()); - display.dispose(); - return; - } - - browser.setText(helpText); - shell.open(); - while (!shell.isDisposed()) { - if (!display.readAndDispatch()) - display.sleep(); - } - - close(); - shell.dispose(); - - } - - /** - * Set isDisposed boolean. - * - * @return boolean - */ - public boolean isDisposed() { - return (shell != null && shell.isDisposed()); - } - - /** - * Bring the dialog to top. - */ - public final void bringToTop() { - if (shell != null && shell.isDisposed() == false) { - shell.setVisible(true); - shell.forceFocus(); - shell.forceActive(); - } - } - - /** - * Closes the shell. - * @return - * boolean - * - */ - public final boolean close() { - if (shell != null && shell.isDisposed() == false) { - shell.dispose(); - } - return true; - } - -} diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/help/DataDeliveryHelpDlg.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/help/DataDeliveryHelpDlg.java new file mode 100644 index 0000000000..3d4bc82d05 --- /dev/null +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/help/DataDeliveryHelpDlg.java @@ -0,0 +1,151 @@ +package com.raytheon.uf.viz.datadelivery.help; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.custom.StyleRange; +import org.eclipse.swt.custom.StyledText; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Layout; +import org.eclipse.swt.widgets.Shell; + +import com.raytheon.uf.common.util.StringUtil; +import com.raytheon.viz.ui.dialogs.CaveSWTDialog; + +/** + * Help dialog for Data Delivery. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * 06/06/2013     2030     mpduff      Initial creation.
+ * 
+ * 
+ * + * @author mpduff + * @version 1.0 + */ + +public class DataDeliveryHelpDlg extends CaveSWTDialog { + /** Styled Text control */ + private StyledText styledText; + + /** List of StyleRange objects */ + private final List ranges = new ArrayList(); + + /** Pattern for 1 or more spaces */ + private static final Pattern pattern = Pattern.compile(" +"); + + /** Help JaxB xml object */ + private final DataDeliveryHelpXML helpXml; + + /** + * Constructor. + * + * @param parentShell + * Parent shell. + * @param helpXml + * The JaxB xml object + */ + + public DataDeliveryHelpDlg(Shell parentShell, DataDeliveryHelpXML helpXml) { + super(parentShell, SWT.DIALOG_TRIM | SWT.MIN | SWT.RESIZE, + CAVE.DO_NOT_BLOCK | CAVE.NO_PACK); + this.helpXml = helpXml; + } + + /* + * (non-Javadoc) + * + * @see com.raytheon.viz.ui.dialogs.CaveSWTDialogBase#constructShellLayout() + */ + @Override + protected Layout constructShellLayout() { + return new GridLayout(1, false); + } + + /* + * (non-Javadoc) + * + * @see + * com.raytheon.viz.ui.dialogs.CaveSWTDialogBase#constructShellLayoutData() + */ + @Override + protected Object constructShellLayoutData() { + return new GridData(SWT.FILL, SWT.DEFAULT, true, false); + } + + /** + * {@inheritDoc} + */ + @Override + protected void initializeComponents(Shell shell) { + GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); + GridLayout gl = new GridLayout(1, false); + shell.setLayout(gl); + shell.setLayoutData(gd); + + gd = new GridData(SWT.FILL, SWT.FILL, true, true); + gl = new GridLayout(1, false); + + styledText = new StyledText(shell, SWT.WRAP | SWT.BORDER | SWT.V_SCROLL); + styledText.setLayout(gl); + styledText.setLayoutData(gd); + + String text = getHelpText(); + styledText.setText(text); + styledText.setLineAlignment(0, 1, SWT.CENTER); + + for (StyleRange sr : ranges) { + styledText.setStyleRange(sr); + } + } + + /** + * {@inheritDoc} + */ + @Override + protected void opened() { + shell.setMinimumSize(400, 600); + } + + /** + * Get the help text from the xml. + * + * @return The help text String + */ + private String getHelpText() { + StringBuilder buffer = new StringBuilder(); + + this.setText(helpXml.getTitle()); + + // indices for style ranges start and end + int startIdx = 0; + for (HelpEntryXML entry : helpXml.getEntryList()) { + startIdx = buffer.length(); + buffer.append(entry.getHeader().trim()).append(StringUtil.NEWLINE); + StyleRange sr = new StyleRange(); + sr.start = startIdx; + sr.length = buffer.length() - startIdx; + sr.fontStyle = SWT.BOLD; + ranges.add(sr); + Matcher matcher = pattern.matcher(entry.getText().trim()); + String text = matcher.replaceAll(" "); + if (text.length() > 0) { + buffer.append(text).append(StringUtil.NEWLINE) + .append(StringUtil.NEWLINE); + } else { + buffer.append(StringUtil.NEWLINE); + } + } + + return buffer.toString(); + } +} diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/help/DataDeliveryHelpXML.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/help/DataDeliveryHelpXML.java new file mode 100644 index 0000000000..b08636f3c1 --- /dev/null +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/help/DataDeliveryHelpXML.java @@ -0,0 +1,93 @@ +/** + * 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.datadelivery.help; + +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.XmlElements; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * JaxB xml object for Data Delivery Help. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 4, 2013    2030     mpduff      Initial creation.
+ * 
+ * 
+ * + * @author mpduff + * @version 1.0 + */ + +@XmlRootElement(name = "Help") +@XmlAccessorType(XmlAccessType.NONE) +public class DataDeliveryHelpXML { + + /** + * The help title. + */ + @XmlElement + private String title; + + /** + * The help topic entries. + */ + @XmlElements({ @XmlElement(name = "helpEntry", type = HelpEntryXML.class) }) + protected List entryList = new ArrayList(); + + /** + * @return the title + */ + public String getTitle() { + return title; + } + + /** + * @param title + * the title to set + */ + public void setTitle(String title) { + this.title = title; + } + + /** + * @return the entryList + */ + public List getEntryList() { + return entryList; + } + + /** + * @param entryList + * the entryList to set + */ + public void setEntryist(List entryList) { + this.entryList = entryList; + } +} diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/help/HelpEntryXML.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/help/HelpEntryXML.java new file mode 100644 index 0000000000..2d2d3a66e2 --- /dev/null +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/help/HelpEntryXML.java @@ -0,0 +1,89 @@ +/** + * 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.datadelivery.help; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * HelpEntry JaxB object. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 4, 2013     2030    mpduff      Initial creation.
+ * 
+ * 
+ * + * @author mpduff + * @version 1.0 + */ + +@XmlRootElement(name = "HelpEntry") +@XmlAccessorType(XmlAccessType.NONE) +public class HelpEntryXML { + + /** + * Help entry header. + */ + @XmlElement + private String header; + + /** + * Help entry text. + */ + @XmlElement + private String text; + + /** + * @return the header + */ + public String getHeader() { + return header; + } + + /** + * @param header + * the header to set + */ + public void setHeader(String header) { + this.header = header; + } + + /** + * @return the text + */ + public String getText() { + return text; + } + + /** + * @param text + * the text to set + */ + public void setText(String text) { + this.text = text; + } +} diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/help/HelpManager.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/help/HelpManager.java new file mode 100644 index 0000000000..d5bd6b3f03 --- /dev/null +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/help/HelpManager.java @@ -0,0 +1,146 @@ +/** + * 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.datadelivery.help; + +import java.util.HashMap; +import java.util.Map; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; + +import org.eclipse.swt.widgets.Shell; + +import com.raytheon.uf.common.localization.IPathManager; +import com.raytheon.uf.common.localization.LocalizationFile; +import com.raytheon.uf.common.localization.PathManagerFactory; +import com.raytheon.uf.common.status.IUFStatusHandler; +import com.raytheon.uf.common.status.UFStatus; +import com.raytheon.uf.common.status.UFStatus.Priority; +import com.raytheon.viz.ui.dialogs.ICloseCallback; + +/** + * Data Delivery Help Dialog manager class. + * + *
+ * 
+ * SOFTWARE HISTORY
+ * 
+ * Date         Ticket#    Engineer    Description
+ * ------------ ---------- ----------- --------------------------
+ * Jun 4, 2013            mpduff     Initial creation
+ * 
+ * 
+ * + * @author mpduff + * @version 1.0 + */ + +public class HelpManager { + /** Status Handler */ + private final IUFStatusHandler statusHandler = UFStatus + .getHandler(HelpManager.class); + + /** Class instance */ + private static HelpManager instance = null; + + /** JAXB context */ + private JAXBContext jax; + + /** Unmarshaller object */ + private Unmarshaller unmarshaller; + + /** Help dialog map for managing open help dialogs */ + private final Map helpMap = new HashMap(); + + /** + * Private constructor. + * + * @throws JAXBException + */ + private HelpManager() throws JAXBException { + createContext(); + } + + /** + * Get the only instance of this class. + * + * @return The instance + * @throws Exception + */ + public static final synchronized HelpManager getInstance() throws Exception { + if (instance == null) { + instance = new HelpManager(); + } + return instance; + } + + /** + * Create the JAXB context + * + * @throws JAXBException + */ + private void createContext() throws JAXBException { + Class[] classes = new Class[] { DataDeliveryHelpXML.class, + HelpEntryXML.class }; + + jax = JAXBContext.newInstance(classes); + this.unmarshaller = jax.createUnmarshaller(); + } + + /** + * Display a help dialog. + * + * @param shell + * The parent shell + * @param helpFile + * The file containing the text + */ + public void displayHelpDialog(Shell shell, final String helpFile) { + if (helpMap.containsKey(helpFile)) { + helpMap.get(helpFile).bringToTop(); + return; + } + + IPathManager pm = PathManagerFactory.getPathManager(); + LocalizationFile locFile = pm.getStaticLocalizationFile(helpFile); + DataDeliveryHelpXML xml = new DataDeliveryHelpXML(); + + if (locFile != null && locFile.exists()) { + try { + xml = (DataDeliveryHelpXML) unmarshaller.unmarshal(locFile + .getFile()); + DataDeliveryHelpDlg helpDlg = new DataDeliveryHelpDlg(shell, xml); + helpDlg.setCloseCallback(new ICloseCallback() { + @Override + public void dialogClosed(Object returnValue) { + helpMap.remove(helpFile); + } + }); + + helpMap.put(helpFile, helpDlg); + helpDlg.open(); + } catch (JAXBException e) { + statusHandler.handle(Priority.ERROR, + "Error displaying help dialog for file " + helpFile, e); + } + } + } +} diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/notification/NotificationDlg.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/notification/NotificationDlg.java index 66c8f2c5a6..ee717a2033 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/notification/NotificationDlg.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/notification/NotificationDlg.java @@ -65,6 +65,7 @@ import com.raytheon.uf.viz.datadelivery.common.ui.ITableChange; import com.raytheon.uf.viz.datadelivery.common.ui.LoadSaveConfigDlg; import com.raytheon.uf.viz.datadelivery.common.ui.LoadSaveConfigDlg.DialogType; import com.raytheon.uf.viz.datadelivery.common.ui.TableCompConfig; +import com.raytheon.uf.viz.datadelivery.help.HelpManager; import com.raytheon.uf.viz.datadelivery.notification.PriorityImages.Priority; import com.raytheon.uf.viz.datadelivery.notification.xml.MessageLoadXML; import com.raytheon.uf.viz.datadelivery.notification.xml.NotificationConfigXML; @@ -97,6 +98,7 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog; * Update title bar text when paused. * Jan 22, 2013 1520 mpduff Change delete menus to hide. * Apr 25, 2013 1820 mpduff Implemente delete config. + * Jun 06, 2013 2030 mpduff Refactored help. * * * @@ -108,7 +110,7 @@ public class NotificationDlg extends CaveSWTDialog implements ITableChange, IMessageLoad, INotificationArrivedListener { /** Status Handler */ - private final transient IUFStatusHandler statusHandler = UFStatus + private final IUFStatusHandler statusHandler = UFStatus .getHandler(NotificationDlg.class); private final String TITLE_TEXT = "Notification Center"; @@ -116,12 +118,12 @@ public class NotificationDlg extends CaveSWTDialog implements ITableChange, /** Find Dialog */ private FindDlg fnd = null; - /** Help Dialog */ - private final NotificationHelpDlg help = null; - /** Message load properties */ private MessageLoadXML messageLoad; + /** Help text file */ + private final String NOTIFICATION_HELP_FILE = "help/notificationHelp.xml"; + /** Path of the Notification Config xml file */ private final String CONFIG_PATH = "dataDelivery" + File.separator + "notificationManagerConfig"; @@ -490,15 +492,13 @@ public class NotificationDlg extends CaveSWTDialog implements ITableChange, * Handle the help display dialog. */ private void handleHelp() { - - if (help == null || help.isDisposed()) { - NotificationHelpDlg help = new NotificationHelpDlg(shell); - help.open(); - help = null; - } else { - help.bringToTop(); + try { + HelpManager.getInstance().displayHelpDialog(shell, + NOTIFICATION_HELP_FILE); + } catch (Exception e) { + statusHandler.error("Error loading Help Text file: " + + NOTIFICATION_HELP_FILE, e); } - } /** diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/notification/NotificationHelpDlg.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/notification/NotificationHelpDlg.java deleted file mode 100644 index a8da1fa8b8..0000000000 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/notification/NotificationHelpDlg.java +++ /dev/null @@ -1,146 +0,0 @@ -package com.raytheon.uf.viz.datadelivery.notification; - -import org.eclipse.swt.widgets.Shell; - -import com.raytheon.uf.viz.datadelivery.help.DataDeliveryHelp; - -/** - * Help dialog for the Notification Table. - * - *
- * 
- * SOFTWARE HISTORY
- * 
- * Date         Ticket#    Engineer    Description
- * ------------ ---------- ----------- --------------------------
- * May 18, 2012   645      jpiatt     Initial creation.
- * 
- * 
- * - * @author jpiatt - * @version 1.0 - */ - -public class NotificationHelpDlg extends DataDeliveryHelp { - - - /** - * Constructor. - * @param parentShell - * Parent shell. - */ - - public NotificationHelpDlg(Shell parentShell) { - - this.parentShell = parentShell; - this.helpText = getHelpText(); - - } - - /** - * Get the Help Text. - * - * @return String - * Help Text. - */ - private String getHelpText() { - - String helpText = "Notification Table Help" + - "The Notification Center Table allows a user to view and delete " + - "data delivery notifications.

" + -// "File
" + -// "Edit
" + -// "Settings

" + - "
" + - "
" + - " File
"+ - "
" + - " Set As Default
" + - " Set the current configuration settings to be the default " + - " settings for the table. When the table is opened the " + - " saved default settings are applied.
" + - " Load Configuration...
" + - " Load a previously saved configuration file. Select from the Available " + - " Configuration Files list and click the Load button to load a configuration " + - " file. Use the Preview button to view the XML associated with the " + - " configuration file.
" + - " Save Configuration
" + - " Save the current configuration settings to the most recently " + - " saved file name. The first time Save Configuration is accessed, " + - " select to save either at the User or Site level and enter a file name. " + - " Click the Save button to save the file. Use the Load Configuration " + - " menu item to load a saved configuration.
" + - " Save Configuration As...
" + - " Save the current configuration settings to a named file " + - " that may be loaded in the future. In the Save Configuration dialog " + - " select to save either at the User or Site level and enter a file name. " + - " Click the Save button to save the file. Use the Load Configuration " + - " menu item to load a saved configuration.
" + - " Delete Configuration...
" + - " Delete a saved configuration file.
" + - " Exit
" + - " Exit the table.

" + - "
" + - " Edit
" + - "
" + - " Find...
" + - " Find and highlight items in the table using the Find dialog. The " + - " Case Sensitive option allows a user to search text that is capitalization " + - " sensitive. The Exclude option allows a user to search the table for " + - " items that exclude the entered text. The Case Sensitive and Exclude options " + - " may be used in conjunction with another. The Column Selection grouping allows " + - " users to search a specific column in the table. After the search criteria " + - " has been selected, click the Find Next button to perform the search. The " + - " Hightlight All button highlights all the rows matching the find " + - " criteria. Close the Find dialog using the Close button.
" + - " Delete by Priority
" + - " Delete all rows in the table having a specific priority. (Note: Notifications " + - " only deleted from the user view and not permanently deleted from the database.)
" + - " Delete Older Than Selected
" + - " Delete all rows in the table having a date in the Time column that is older " + - " than the currently highlighted row. (Note: Notifications
" + - " only deleted from the user view and not permanently deleted from the database.)
" + - " Delete Notification(s)
" + - " Delete the currently highlighted row(s) in the table. (Note: Notifications " + - " only deleted from the user view and not permanently deleted from the database.)

" + - "
" + - " Settings
" + - "
" + - " Configure Table...
" + - " The Initial Startup Configuration items are set when the table is opened. " + - " Check the Load All Messages check box to display all messages in the table that " + - " are contained in the database. Enter a number of messages or hours amount in the " + - " Load Last spinner to select the amount of messages or number of hours of messages " + - " to display in the table. Set the Initial Sort Column and either Sort Ascending " + - " or Sort Descending to sort the table by a specific colum upon opening. " + - "
The Display Configuration items refresh the table upon clicking OK. Select the " + - " number of Rows Per Page using the selection drop down. Select the image setting " + - " for the Priority table column using the radio buttons. Select to make columns " + - " hidden or visible using the arrows provided. After making selections, click the OK" + - " button to configure the table. (Note: Unless the configuration is set to the default " + - " or saved, changes will be lost when the table is closed.)
" + - " Filter Table...
" + - " A user may filter the table by user, by subscription or by priority.
In the Filter by " + - " User section, the list of available user names are in the Available Users column. If users are moved " + - " to the Selected Users list, the corresponding columns containing those user names will be " + - " displayed in the Notification Table. Use the arrows to move users back and forth from the " + - " Available Users list to the Selected Users list. (Note: User names are not duplicated and " + - " appear only once either in the Available or Selected lists.) The Always include my notifications " + - " check box may be used to keep the currently logged in user in the Selected Users column. " + - "
In the Filter by Subscription section, the list of available subscription names are in the " + - " Available Subscriptions column. If subscriptions are moved to the Selected Subscriptions list " + - " the corresponding columns containing those subscription names will be displayed in the " + - " Notification Table. Use the arrows to move subscriptions back and forth from the " + - " Available Subscriptions list to the Selected Subscriptions list. (Note: Subscription " + - " names are not duplicated and appear only once either in the Available or Selected lists.)" + - "
In the Filter by Priority section, select which columns containing specific priorities to " + - " display using the checkboxes." + - "
" + - ""; - - return helpText; - - } - -} - diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/CancelForceApplyAndIncreaseLatencyDisplayText.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/CancelForceApplyAndIncreaseLatencyDisplayText.java index e3d5702ed7..4df123b53d 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/CancelForceApplyAndIncreaseLatencyDisplayText.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/CancelForceApplyAndIncreaseLatencyDisplayText.java @@ -38,6 +38,7 @@ import com.raytheon.uf.viz.datadelivery.subscription.SubscriptionService.IForceA * Date Ticket# Engineer Description * ------------ ---------- ----------- -------------------------- * Dec 4, 2012 1286 djohnson Initial creation + * May 28, 2013 1650 djohnson More information when failing to schedule subscriptions. * * * @@ -78,17 +79,22 @@ public class CancelForceApplyAndIncreaseLatencyDisplayText implements int requiredLatency, Subscription subscription, Set wouldBeUnscheduledSubscriptions) { final String name = subscription.getName(); + final boolean singleSubscription = wouldBeUnscheduledSubscriptions + .size() == 1; switch (option) { case CANCEL: return "Do not " + actionText + " " + name; case FORCE_APPLY: - if (wouldBeUnscheduledSubscriptions.size() == 1 + if (singleSubscription && wouldBeUnscheduledSubscriptions.contains(name)) { return titleCaseActionText + " " + name + " and leave in an unscheduled status"; } return titleCaseActionText + " " + name + " and unschedule the others"; + case EDIT_SUBSCRIPTIONS: + return "Edit the " + + ((singleSubscription) ? "subscription" : "subscriptions"); case INCREASE_LATENCY: return "Increase the latency on " + name + " to " + requiredLatency + " minutes"; diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/CreateSubscriptionDlg.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/CreateSubscriptionDlg.java index 1b9b757202..f7bc585894 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/CreateSubscriptionDlg.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/CreateSubscriptionDlg.java @@ -44,9 +44,12 @@ import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import com.raytheon.uf.common.auth.user.IUser; +import com.raytheon.uf.common.datadelivery.registry.DataType; +import com.raytheon.uf.common.datadelivery.registry.PointTime; import com.raytheon.uf.common.datadelivery.registry.Subscription; import com.raytheon.uf.common.datadelivery.registry.Subscription.SubscriptionPriority; import com.raytheon.uf.common.datadelivery.registry.ebxml.DataSetQuery; +import com.raytheon.uf.common.datadelivery.request.DataDeliveryConstants; import com.raytheon.uf.common.datadelivery.request.DataDeliveryPermission; import com.raytheon.uf.common.status.IUFStatusHandler; import com.raytheon.uf.common.status.UFStatus; @@ -97,6 +100,8 @@ import com.raytheon.viz.ui.presenter.components.CheckBoxConf; * Jan 25, 2013 1528 djohnson Use priority enum instead of raw integers. * Apr 08, 2013 1826 djohnson Remove delivery options. * May 15, 2013 1040 mpduff Add Shared sites. + * Jun 04, 2013 223 mpduff Modify for point data. + * Jun 12, 2013 2038 djohnson No longer modal. * * * @@ -181,7 +186,7 @@ public class CreateSubscriptionDlg extends CaveSWTDialog implements * true for new subscription, false for edit */ public CreateSubscriptionDlg(Shell parent, boolean create) { - super(parent, SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL, + super(parent, SWT.DIALOG_TRIM, CAVE.INDEPENDENT_SHELL | CAVE.PERSPECTIVE_INDEPENDENT); this.create = create; @@ -218,13 +223,25 @@ public class CreateSubscriptionDlg extends CaveSWTDialog implements activePeriodComp = new ActivePeriodComp(mainComp); // Get latency value + int latency = 15; + SubscriptionPriority priority = SubscriptionPriority.NORMAL; SystemRuleManager ruleManager = SystemRuleManager.getInstance(); - int latency = ruleManager.getLatency(this.subscription, cycleTimes); - SubscriptionPriority priority = ruleManager.getPriority( - this.subscription, cycleTimes); - priorityComp = new PriorityComp(mainComp, latency, priority); - this.createCycleGroup(); + if (this.subscription.getDataSetType() == DataType.GRID) { + latency = ruleManager.getLatency(subscription, cycleTimes); + priority = ruleManager.getPriority(subscription, cycleTimes); + priorityComp = new PriorityComp(mainComp, latency, priority, false); + } else if (this.subscription.getDataSetType() == DataType.POINT) { + // For point the latency is the retrieval interval + latency = ((PointTime) subscription.getTime()).getInterval(); + priority = ruleManager.getPointDataPriority(subscription); + priorityComp = new PriorityComp(mainComp, latency, priority, true); + } + + if (this.subscription.getDataSetType() == DataType.GRID) { + this.createCycleGroup(); + } + createSiteSelection(); if (create == false) { @@ -303,86 +320,89 @@ public class CreateSubscriptionDlg extends CaveSWTDialog implements GridData gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); GridLayout gl = new GridLayout(2, false); - final Group group = new Group(mainComp, SWT.NONE); - group.setLayout(gl); - group.setLayoutData(gd); - group.setText(" Shared Sites "); + if (DataDeliveryConstants.PHASE3_ENABLED) { + final Group group = new Group(mainComp, SWT.NONE); + group.setLayout(gl); + group.setLayoutData(gd); + group.setText(" Shared Sites "); - gd = new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false); - gl = new GridLayout(2, false); - final Composite c = new Composite(group, SWT.NONE); - c.setLayout(gl); - c.setLayoutData(gd); + gd = new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false); + gl = new GridLayout(2, false); + final Composite c = new Composite(group, SWT.NONE); + c.setLayout(gl); + c.setLayoutData(gd); - gl = new GridLayout(1, false); - gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); - final Button btn = new Button(c, SWT.NONE); - btn.setLayoutData(new GridData(95, SWT.DEFAULT)); - btn.setText("Select Sites..."); - btn.setToolTipText("Select sites for sharing"); - btn.setEnabled(false); + gl = new GridLayout(1, false); + gd = new GridData(SWT.FILL, SWT.DEFAULT, true, false); + final Button btn = new Button(c, SWT.NONE); + btn.setLayoutData(new GridData(95, SWT.DEFAULT)); + btn.setText("Select Sites..."); + btn.setToolTipText("Select sites for sharing"); + btn.setEnabled(false); - final DataDeliveryPermission permission = DataDeliveryPermission.SHARED_SUBSCRIPTION_CREATE; - final IUser user = UserController.getUserObject(); - final String msg = user.uniqueId() - + " is not authorized to create shared subscriptions. " - + StringUtil.NEWLINE + "Permission: " + permission; - try { - if (DataDeliveryServices.getPermissionsService() - .checkPermission(user, msg, permission).isAuthorized()) { - btn.setEnabled(true); - } else { - c.addMouseTrackListener(new MouseTrackAdapter() { + final DataDeliveryPermission permission = DataDeliveryPermission.SHARED_SUBSCRIPTION_CREATE; + final IUser user = UserController.getUserObject(); + final String msg = user.uniqueId() + + " is not authorized to create shared subscriptions. " + + StringUtil.NEWLINE + "Permission: " + permission; + try { + if (DataDeliveryServices.getPermissionsService() + .checkPermission(user, msg, permission).isAuthorized()) { + btn.setEnabled(true); + } else { + c.addMouseTrackListener(new MouseTrackAdapter() { - @Override - public void mouseExit(MouseEvent e) { - DataDeliveryGUIUtils.hideToolTip(); - } - - @Override - public void mouseHover(MouseEvent e) { - handleMouseEvent(e, msg, group.getBounds()); - } - - @Override - public void mouseEnter(MouseEvent e) { - handleMouseEvent(e, msg, group.getBounds()); - } - }); - } - } catch (VizException e1) { - statusHandler - .handle(Priority.PROBLEM, e1.getLocalizedMessage(), e1); - } - btn.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - SiteSelectionDlg dlg = new SiteSelectionDlg(shell, "OAX", - sharedSites); - dlg.setCloseCallback(new ICloseCallback() { - @Override - public void dialogClosed(Object returnValue) { - if (returnValue instanceof String[]) { - String[] sites = (String[]) returnValue; - processSites(sites); + @Override + public void mouseExit(MouseEvent e) { + DataDeliveryGUIUtils.hideToolTip(); } - } - }); - dlg.open(); + + @Override + public void mouseHover(MouseEvent e) { + handleMouseEvent(e, msg, group.getBounds()); + } + + @Override + public void mouseEnter(MouseEvent e) { + handleMouseEvent(e, msg, group.getBounds()); + } + }); + } + } catch (VizException e1) { + statusHandler.handle(Priority.PROBLEM, + e1.getLocalizedMessage(), e1); } - }); + btn.addSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + SiteSelectionDlg dlg = new SiteSelectionDlg(shell, "OAX", + sharedSites); + dlg.setCloseCallback(new ICloseCallback() { + @Override + public void dialogClosed(Object returnValue) { + if (returnValue instanceof String[]) { + String[] sites = (String[]) returnValue; + processSites(sites); + } + } + }); + dlg.open(); + } + }); - selectedSiteLbl = new Label(group, SWT.BORDER); - selectedSiteLbl.setFont(font); - selectedSiteLbl.setText(""); - selectedSiteLbl.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, - false)); + selectedSiteLbl = new Label(group, SWT.BORDER); + selectedSiteLbl.setFont(font); + selectedSiteLbl.setText(""); + selectedSiteLbl.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, + true, false)); - if (!create) { - if (subscription != null && subscription.getOfficeIDs().size() > 0) { - String[] siteArr = subscription.getOfficeIDs().toArray( - new String[subscription.getOfficeIDs().size()]); - processSites(siteArr); + if (!create) { + if (subscription != null + && subscription.getOfficeIDs().size() > 0) { + String[] siteArr = subscription.getOfficeIDs().toArray( + new String[subscription.getOfficeIDs().size()]); + processSites(siteArr); + } } } } @@ -727,12 +747,15 @@ public class CreateSubscriptionDlg extends CaveSWTDialog implements okBtn.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { - status = Status.OK; - getShell().setCursor( - getDisplay().getSystemCursor(SWT.CURSOR_WAIT)); - okConf.getOnClickAction().run(); - if (!getShell().isDisposed()) { - getShell().setCursor(null); + try { + status = Status.OK; + getShell().setCursor( + getDisplay().getSystemCursor(SWT.CURSOR_WAIT)); + okConf.getOnClickAction().run(); + } finally { + if (!getShell().isDisposed()) { + getShell().setCursor(null); + } } } }); diff --git a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/DisplayForceApplyPromptDialog.java b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/DisplayForceApplyPromptDialog.java index 0cbfced6c9..189a34303b 100644 --- a/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/DisplayForceApplyPromptDialog.java +++ b/cave/com.raytheon.uf.viz.datadelivery/src/com/raytheon/uf/viz/datadelivery/subscription/DisplayForceApplyPromptDialog.java @@ -19,52 +19,49 @@ **/ package com.raytheon.uf.viz.datadelivery.subscription; -import java.util.Set; - import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionAdapter; import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.List; import org.eclipse.swt.widgets.Shell; +import com.google.common.collect.Lists; import com.raytheon.uf.common.datadelivery.registry.Subscription; +import com.raytheon.uf.common.util.SizeUtil; import com.raytheon.uf.viz.datadelivery.subscription.SubscriptionService.ForceApplyPromptResponse; import com.raytheon.uf.viz.datadelivery.subscription.SubscriptionService.IForceApplyPromptDisplayText; import com.raytheon.viz.ui.dialogs.CaveSWTDialog; /** - * TODO Add Description + * Dialog allowing the user to choose how to continue with their subscription + * creation/modification request. * *
- *
+ * 
  * SOFTWARE HISTORY
- *
+ * 
  * Date         Ticket#    Engineer    Description
  * ------------ ---------- ----------- --------------------------
  * Nov 29, 2012            djohnson     Initial creation
- *
+ * May 22, 2013 1650       djohnson     Add more bandwidth information.
+ * Jun 12, 2013 2038       djohnson     Maximum allowed size is returned in kilobytes.
+ * 
  * 
- * + * * @author djohnson - * @version 1.0 + * @version 1.0 */ public class DisplayForceApplyPromptDialog extends CaveSWTDialog { - private final String dialogTitle; - private final String message; - - private final int requiredLatency; - - private final IForceApplyPromptDisplayText displayTextStrategy; - - private final Subscription subscription; - - private final Set wouldBeUnscheduledSubscriptions; + private final ForceApplyPromptConfiguration configuration; /** * Constructor. @@ -75,61 +72,99 @@ public class DisplayForceApplyPromptDialog extends CaveSWTDialog { * @param subscription * @param wouldBeUnscheduledSubscriptions */ - public DisplayForceApplyPromptDialog(String title, String message, - int requiredLatency, - IForceApplyPromptDisplayText displayTextStrategy, - Subscription subscription, - Set wouldBeUnscheduledSubscriptions) { - super(displayTextStrategy.getShell()); + public DisplayForceApplyPromptDialog( + ForceApplyPromptConfiguration configuration) { + super(configuration.displayTextStrategy.getShell()); - this.dialogTitle = title; - this.message = message; - this.requiredLatency = requiredLatency; - this.displayTextStrategy = displayTextStrategy; - this.subscription = subscription; - this.wouldBeUnscheduledSubscriptions = wouldBeUnscheduledSubscriptions; + this.configuration = configuration; } /** * {@inheritDoc} - * @param subscription + * + * @param subscription */ @Override protected void initializeComponents(final Shell shell) { - setText(dialogTitle); + setText(configuration.title); // Initialize layout - GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true); + GridData gd = new GridData(SWT.FILL, SWT.FILL, false, true); gd.widthHint = 400; - gd.heightHint = 100; Label textLabel = new Label(shell, SWT.WRAP); textLabel.setLayoutData(gd); - textLabel.setText(message); + textLabel.setText(configuration.message); + + if (configuration.hasUnscheduledSubscriptions()) { + Composite unscheduledSubscriptionsComp = new Composite(shell, + SWT.NONE); + unscheduledSubscriptionsComp.setLayout(new GridLayout(1, false)); + unscheduledSubscriptionsComp.setLayoutData(new GridData(SWT.FILL, + SWT.FILL, true, true)); + + final List list = new List(unscheduledSubscriptionsComp, SWT.MULTI + | SWT.BORDER); + list.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + final SelectionListener listener = new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + list.deselectAll(); + } + }; + list.setItems(configuration.wouldBeUnscheduledSubscriptions + .toArray(new String[configuration.wouldBeUnscheduledSubscriptions + .size()])); + list.addSelectionListener(listener); + } + + if (configuration.hasBandwidthDetails()) { + Group group = new Group(shell, SWT.BORDER); + group.setText("Bandwidth Details"); + group.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + group.setLayout(new GridLayout(1, false)); + + Label rulesLatency = new Label(group, SWT.WRAP); + rulesLatency.setText("Maximum latency recommended by rules: " + + configuration.maximumLatency + " minutes"); + rulesLatency.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, + true)); + + Label sizeLabel = new Label(group, SWT.WRAP); + sizeLabel + .setText("Maximum allowed size with current latency: " + + SizeUtil + .prettyKiloByteSize(configuration.maximumAllowedSize)); + sizeLabel + .setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + } + + Composite leftComp = new Composite(shell, SWT.NONE); + leftComp.setLayout(new GridLayout(1, false)); + leftComp.setLayoutData(new GridData(SWT.LEFT, SWT.DEFAULT, true, false)); + + Label choiceLabel = new Label(leftComp, SWT.WRAP); + choiceLabel.setLayoutData(gd); + choiceLabel.setText("\nWhat would you like to do?\n"); // Add radio buttons - Composite leftComp = new Composite(shell, SWT.NONE); - GridLayout gl = new GridLayout(1, false); - leftComp.setLayout(gl); - GridData gd2 = new GridData(SWT.LEFT, SWT.DEFAULT, true, false); - leftComp.setLayoutData(gd2); - - Button[] radios = getRadioButtons(leftComp, requiredLatency, - displayTextStrategy, subscription); + Button[] radios = getRadioButtons(leftComp, + configuration.requiredLatency, + configuration.displayTextStrategy, configuration.subscription); radios[0].setSelection(true); setReturnValue(ForceApplyPromptResponse.CANCEL); + radios[0].setFocus(); - // Add a close button + // Add an OK button Composite centeredComp = new Composite(shell, SWT.NONE); - gl = new GridLayout(1, false); - centeredComp.setLayout(gl); - gd2 = new GridData(SWT.CENTER, SWT.DEFAULT, true, false); - centeredComp.setLayoutData(gd2); + centeredComp.setLayout(new GridLayout(1, false)); + gd = new GridData(SWT.CENTER, SWT.DEFAULT, true, false); + centeredComp.setLayoutData(gd); - Button closeBtn = new Button(centeredComp, SWT.NONE); - closeBtn.setText("OK"); - closeBtn.setLayoutData(gd2); - closeBtn.addSelectionListener(new SelectionAdapter() { + Button okBtn = new Button(centeredComp, SWT.NONE); + okBtn.setText("OK"); + okBtn.setLayoutData(gd); + okBtn.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent event) { shell.dispose(); @@ -158,30 +193,29 @@ public class DisplayForceApplyPromptDialog extends CaveSWTDialog { .values(); final int length = values.length; - Button[] buttons = new Button[length]; + java.util.List