Issue #1496 Changes to move what may be long queries off the UI thread.

Changed based on comments in patch set 2.

Change-Id: I867f716aac39562f9b8bfaddf187bc80cb5a71ce

Former-commit-id: 7dad868adf [formerly 3abb6f1026] [formerly ff09ee32ab] [formerly 7dad868adf [formerly 3abb6f1026] [formerly ff09ee32ab] [formerly 470abe2495 [formerly ff09ee32ab [formerly e54cc8fa001f3c6584bc40a74f461d7021ef77bb]]]]
Former-commit-id: 470abe2495
Former-commit-id: 9d57e63501 [formerly 3daf0c7b37] [formerly 74c0f2f92451f0a414ebfbb04887d41f50debf92 [formerly 58e3bbbe97]]
Former-commit-id: 7604f050d118297b35ef8a8d6731fe102bc5cfe5 [formerly e0c01d6c04]
Former-commit-id: 067198ca1f
This commit is contained in:
Roger Ferrel 2013-01-22 14:33:22 -06:00
parent b30f963db9
commit 04e20890ea
5 changed files with 1499 additions and 195 deletions

View file

@ -0,0 +1,52 @@
/**
* 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.viz.texteditor.command;
import java.util.List;
import com.raytheon.uf.common.dataplugin.text.db.StdTextProduct;
/**
* Interface used by ProductQueryJob to return the information from a query
* request.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jan 18, 2013 rferrel Initial creation
*
* </pre>
*
* @author rferrel
* @version 1.0
*/
public interface IProductQueryCallback {
/**
* @param command
* @param prodList
* @param isObsUpdated
*/
public void requestDone(ICommand command, List<StdTextProduct> prodList,
boolean isObsUpdated);
}

View file

@ -0,0 +1,222 @@
/**
* 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.viz.texteditor.command;
import java.util.ArrayList;
import java.util.List;
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.dataplugin.text.db.StdTextProduct;
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.edex.services.textdbsrv.IQueryTransport;
import com.raytheon.uf.viz.core.VizApp;
import com.raytheon.viz.texteditor.util.TextEditorUtil;
/**
* Job to perform queries for text products.
*
* <pre>
*
* SOFTWARE HISTORY
*
* Date Ticket# Engineer Description
* ------------ ---------- ----------- --------------------------
* Jan 18, 2013 rferrel Initial creation
*
* </pre>
*
* @author rferrel
* @version 1.0
*/
public class ProductQueryJob extends Job {
private final IUFStatusHandler statusHandler = UFStatus
.getHandler(ProductQueryJob.class);
private final IProductQueryCallback callback;
/**
* flag to indicate request accumulate.
*/
private boolean accumulate;
/**
* List queries to perform.
*/
private final List<Request> requests;
/**
* Transport to use for the queries.
*/
private final IQueryTransport queryTransport;
/**
* Flag to indicate cancel is being performed.
*/
private final AtomicBoolean canceled;
public ProductQueryJob(IProductQueryCallback callback) {
super("Product Query");
setSystem(true);
this.callback = callback;
accumulate = false;
requests = new ArrayList<Request>();
queryTransport = TextEditorUtil.getTextDbsrvTransport();
canceled = new AtomicBoolean(false);
}
/**
* Add request to queue and determine what needs to be done to schedule the
* request.
*
* @param command
* @param isObsUpdated
*/
public synchronized void addRequest(ICommand command, boolean isObsUpdated) {
Request request = new Request(command, isObsUpdated);
if (accumulate) {
requests.add(request);
if (getState() == Job.NONE) {
schedule();
}
} else {
requests.clear();
requests.add(request);
if (getState() == Job.NONE) {
schedule();
} else {
cancel();
}
}
}
public boolean isAccumulate() {
return accumulate;
}
/**
* When set to true requests will accumulate and be processed in the order
* received; otherwise the queue is purged and any current request is
* canceled if a new request is received.
*
* @param accumulate
*/
public void setAccumulate(boolean accumulate) {
if (this.accumulate != accumulate) {
synchronized (this) {
requests.clear();
if (getState() != Job.NONE) {
cancel();
}
this.accumulate = accumulate;
}
}
}
/*
* (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;
}
Request request = null;
while (!canceled.get()) {
synchronized (this) {
if (requests.size() > 0) {
request = requests.remove(0);
} else {
break;
}
}
try {
final ICommand command = request.getCommand();
final boolean isObsUpdated = request.isObsUpdated();
final List<StdTextProduct> prodList = command
.executeCommand(queryTransport);
// User may have canceled while long query is be performed.
if (!canceled.get()) {
VizApp.runAsync(new Runnable() {
@Override
public void run() {
callback.requestDone(command, prodList,
isObsUpdated);
}
});
} else {
canceled.set(false);
}
} catch (CommandFailedException e) {
statusHandler.handle(Priority.PROBLEM, e.getLocalizedMessage(),
e);
callback.requestDone(null, null, false);
}
}
canceled.set(false);
return Status.OK_STATUS;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.runtime.jobs.Job#canceling()
*/
@Override
protected void canceling() {
canceled.set(true);
}
/*
* Class to hold the query command and isObsUpdated flag needed for the
* query and its callback.
*/
private static class Request {
private ICommand command;
private boolean isObsUpdated;
public Request(ICommand command, boolean isObsUpdated) {
this.command = command;
this.isObsUpdated = isObsUpdated;
}
public ICommand getCommand() {
return command;
}
public boolean isObsUpdated() {
return isObsUpdated;
}
}
}

View file

@ -23,8 +23,13 @@ package com.raytheon.viz.texteditor.dialogs;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Iterator;
import java.util.SortedSet;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.MenuManager;
@ -55,9 +60,13 @@ import com.raytheon.edex.textdb.dbapi.impl.AFOS_CLASS;
import com.raytheon.edex.textdb.dbapi.impl.AFOS_ORIGIN;
import com.raytheon.uf.common.message.Message;
import com.raytheon.uf.common.message.Property;
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.edex.decodertools.time.TimeTools;
import com.raytheon.uf.edex.services.textdbsrv.IQueryTransport;
import com.raytheon.uf.edex.services.textdbsrv.TextDBQuery;
import com.raytheon.uf.viz.core.VizApp;
import com.raytheon.uf.viz.core.localization.LocalizationManager;
import com.raytheon.viz.core.mode.CAVEMode;
import com.raytheon.viz.texteditor.AfosBrowserModel;
@ -88,6 +97,8 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
* functionality.
* 06/28/2010 3283 cjeanbap Implement window resize.
* 25Sep2012 1196 lvenable Dialog refactor to prevent blocking.
* 22Jan2013 1496 rferrel Changes to designator hours query
* off the UI thread.
* </pre>
*
* @author lvenable
@ -95,6 +106,9 @@ import com.raytheon.viz.ui.dialogs.CaveSWTDialog;
public class AfosBrowserDlg extends CaveSWTDialog implements
ITextWorkstationCallback {
private static final transient IUFStatusHandler statusHandler = UFStatus
.getHandler(AwipsBrowserDlg.class);
private static final String TIME_FORMAT = "%1$tH:%1$tM %1$tb %1$td";
private final AfosBrowserModel browserData = AfosBrowserModel.getInstance();
@ -103,6 +117,41 @@ public class AfosBrowserDlg extends CaveSWTDialog implements
NODE, CATEGORY, DESIGNATOR, DESIGNATOR_TIME, DISPLAY
};
/**
* Designator time display error for getting data for designator.
*/
private final String DATA_ERROR = "ERROR";
/**
* Designator time display when no data retrieved for designator.
*/
private final String DATA_NONE = "NO DATA";
/**
* Designator time display while data retrieval is pending.
*/
private final String DATA_LOADING = "??:?? ??? ??";
/**
* Flag to indicate loading of designator times is active.
*/
private boolean loadingProduct = false;
/**
* Flag to indicate loading of product(s) is active in the parent's dialog.
*/
private boolean loadingTimes = false;
/**
* Newest time used to populate "000" designator's time.
*/
private long newestTime = -1L;
/**
* Index of designator who time is being updated.
*/
private int dtlIndex;
/**
* custom mouse handling so we can do the required vertical bar
* non-scrolling.
@ -153,36 +202,16 @@ public class AfosBrowserDlg extends CaveSWTDialog implements
*/
private String selectedNode;
/**
* The node index that is selected.
*/
private int selectedNodeIndex = -1;
/**
* The category that is selected.
*/
private String selectedCategory;
/**
* The category index that is selected.
*/
private int selectedCategoryIndex = -1;
/**
* The designator that is selected.
*/
private String selectedDesignator;
/**
* The designator index that is selected.
*/
private int selectedDesignatorIndex = -1;
/**
* The designator time that is selected.
*/
private String selectedDesignatorTime;
/**
* Load the text product and keep the browser dialog open.
*/
@ -217,6 +246,8 @@ public class AfosBrowserDlg extends CaveSWTDialog implements
private MenuManager menuMgr = null;
private QueryRequests queryRequests = new QueryRequests();
/**
* Constructor.
*
@ -241,11 +272,23 @@ public class AfosBrowserDlg extends CaveSWTDialog implements
queryTransport = TextEditorUtil.getTextDbsrvTransport();
}
/*
* (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#initializeComponents(org
* .eclipse.swt.widgets.Shell)
*/
@Override
protected void initializeComponents(Shell shell) {
initializeComponents();
@ -575,6 +618,10 @@ public class AfosBrowserDlg extends CaveSWTDialog implements
});
}
/**
* Allow parent dialog to display the hidden dialog or just force it to the
* top of the display.
*/
public void showDialog() {
bringToTop();
isAfosActive = true;
@ -614,7 +661,12 @@ public class AfosBrowserDlg extends CaveSWTDialog implements
vBar2.addSelectionListener(listener2);
}
/**
* Create a query command and a list of product ids to obtain the hours for
* and pass the request off to the query request job.
*/
private void queryTableUsingNodeAndCategory() {
getShell().setCursor(getDisplay().getSystemCursor(SWT.CURSOR_WAIT));
TextDBQuery dbQuery = new TextDBQuery(queryTransport);
dbQuery.setQueryViewName("text");
dbQuery.setQueryOpName("GET");
@ -627,18 +679,68 @@ public class AfosBrowserDlg extends CaveSWTDialog implements
dbQuery.setQueryOperationalMode(result.toString().toUpperCase());
// Build up the query list.
java.util.List<String> productIds = new ArrayList<String>();
for (int i = 1; i < designatorList.getItemCount(); i++) {
String prodId = selectedNode + selectedCategory
+ designatorList.getItem(i);
dbQuery.addProductId(prodId);
productIds.add(prodId);
}
Message queryResponse = dbQuery.executeQuery();
queryRequests.addRequest(dbQuery, productIds);
}
/**
* Set up designator Time list to be the same size as designator list
* populated with loading template; and set up variables needed for queries.
*/
private void startDesignatorTimeList() {
loadingTimes = true;
getShell().setCursor(getDisplay().getSystemCursor(SWT.CURSOR_WAIT));
newestTime = -1L;
designatorTimeList.removeAll();
int cnt = designatorList.getItemCount();
for (int i = 1; i < cnt; ++i) {
designatorTimeList.add(DATA_LOADING);
}
// Keep this list the same size as disignatorList.
designatorTimeList.add("");
updateSelectionList(designatorTimeList);
dtlIndex = 0;
}
/**
* Finish setup of designator time list after all times have been retrieved.
*/
private void finishDesignatorTimeList() {
String value = null;
if (newestTime > 0L) {
Calendar c = TimeTools.newCalendar(newestTime);
value = String.format(TIME_FORMAT, c);
} else if (newestTime == -1) {
value = DATA_ERROR;
} else {
value = DATA_NONE;
}
designatorTimeList.setItem(0, value);
loadingTimes = false;
if (!loadingProduct) {
getShell().setCursor(null);
}
}
/**
* Update the the next chuck of times retrieved. Assume these values should
* be inserted staring at dtlIndex+1.
*
* @param queryResponse
*/
private void updateAfterQuery(Message queryResponse) {
Property[] properties = queryResponse.getHeader().getProperties();
ArrayList<Long> times = new ArrayList<Long>();
// We use this time to populate the "000" designator entry.
long newestTime = -1L;
if (properties != null) {
for (Property p : properties) {
if ("STDOUT".equals(p.getName())) {
@ -651,38 +753,81 @@ public class AfosBrowserDlg extends CaveSWTDialog implements
}
}
designatorTimeList.removeAll();
if (newestTime > 0) {
Calendar c = TimeTools.newCalendar(newestTime);
designatorTimeList.add(String.format(TIME_FORMAT, c));
} else if (newestTime == -1) {
designatorTimeList.add("ERROR");
} else {
designatorTimeList.add("NO DATA");
}
for (Long time : times) {
if (time > 0) {
Calendar c = TimeTools.newCalendar(time);
designatorTimeList.add(String.format(TIME_FORMAT, c));
} else if (time == -1) {
designatorTimeList.add("ERROR");
} else {
designatorTimeList.add("NO DATA");
String value = null;
try {
int startIndex = dtlIndex;
int selectIndex = designatorList.getSelectionIndex();
for (Long time : times) {
++dtlIndex;
if (time > 0) {
Calendar c = TimeTools.newCalendar(time);
value = String.format(TIME_FORMAT, c);
} else if (time == -1) {
value = DATA_ERROR;
} else {
value = DATA_NONE;
}
designatorTimeList.setItem(dtlIndex, value);
}
// Selected designator time updated check status of load buttons.
if (selectIndex > startIndex && selectIndex <= dtlIndex) {
checkLoadBtn();
}
} catch (IllegalArgumentException ex) {
// ignore caused by cancel being performed.
}
}
/*
* (non-Javadoc)
*
* @see
* com.raytheon.viz.texteditor.msgs.ITextWorkstationCallback#isAfosBrowserActive
* ()
*/
@Override
public boolean isAfosBrowserActive() {
return isAfosActive;
}
/**
* Handles setting up status of this dialog when parent is loading
* product(s).
*
* @param status
* - true when active loading product(s) otherwise false.
*/
public void setLoading(boolean status) {
if (loadingProduct != status) {
loadingProduct = status;
if (!loadingTimes) {
if (loadingProduct) {
setLoadBtnEnabled(false);
shell.setCursor(getDisplay().getSystemCursor(
SWT.CURSOR_WAIT));
} else {
setLoadBtnEnabled(designatorTimeList.getSelectionIndex() != -1);
shell.setCursor(null);
}
}
}
}
/**
* Convince method for keeping the handling of load buttons the same.
*
* @param flag
*/
private void setLoadBtnEnabled(boolean flag) {
loadContinueBtn.setEnabled(flag);
loadCloseBtn.setEnabled(flag);
}
/**
* Loads the node list. Assumes the query for the list will not hang up the
* UI thread.
*/
private void loadNodeList() {
setLoadBtnEnabled(false);
nodeList.removeAll();
@ -703,6 +848,10 @@ public class AfosBrowserDlg extends CaveSWTDialog implements
updateSelectionList(nodeList);
}
/**
* Populate the category list. Assumes query for the list will not hang up
* the UI thread.
*/
private void loadCategoryList() {
setLoadBtnEnabled(false);
categoryList.removeAll();
@ -735,6 +884,10 @@ public class AfosBrowserDlg extends CaveSWTDialog implements
updateSelectionList(categoryList);
}
/**
* Load the designator list Assumes query for the list will not hang up the
* UI thread.
*/
private void loadDesignatorList() {
setLoadBtnEnabled(false);
designatorList.removeAll();
@ -775,17 +928,25 @@ public class AfosBrowserDlg extends CaveSWTDialog implements
designatorTimeList.add("");
}
updateSelectionList(designatorList);
updateSelectionList(designatorTimeList);
loadDisplayList();
}
/**
* Create a boolean array initialized to false that is the same size as the
* list and place it in the list's data object.
*
* @param list
*/
private void updateSelectionList(List list) {
boolean[] selectedIndexes = new boolean[list.getItemCount()];
Arrays.fill(selectedIndexes, false);
list.setData(selectedIndexes);
}
/**
* Update the Display list based on the selected category and designator.
*/
private void loadDisplayList() {
displayList.removeAll();
@ -811,8 +972,12 @@ public class AfosBrowserDlg extends CaveSWTDialog implements
}
}
/**
* Set selected node and update AFOS command and the category list.
*
* @param index
*/
private void selectNode(int index) {
selectedNodeIndex = index;
selectedNode = nodeList.getItem(index);
nodeList.setSelection(index);
nodeList.showSelection();
@ -820,8 +985,13 @@ public class AfosBrowserDlg extends CaveSWTDialog implements
loadCategoryList();
}
/**
* Update the category list selection, the AFOS command and start load the
* designator lists.
*
* @param index
*/
private void selectCategory(int index) {
selectedCategoryIndex = index;
selectedCategory = categoryList.getItem(index);
categoryList.setSelection(index);
categoryList.showSelection();
@ -829,18 +999,28 @@ public class AfosBrowserDlg extends CaveSWTDialog implements
loadDesignatorList();
}
/**
* Update the selected designator, the AFOS command and it the designator's
* hour is valid enable the load buttons.
*
* @param index
*/
private void selectDesignator(int index) {
String tmp = designatorList.getItem(index);
if (tmp.length() > 0) {
selectedDesignatorIndex = index;
selectedDesignator = designatorList.getItem(index);
selectedDesignatorTime = designatorTimeList.getItem(index);
designatorList.setSelection(index);
designatorTimeList.setSelection(index);
designatorList.showSelection();
designatorTimeList.showSelection();
setAFOSCommand(selectedNode + selectedCategory + selectedDesignator);
try {
selectedDesignator = designatorList.getItem(index);
designatorList.setSelection(index);
designatorTimeList.setSelection(index);
designatorList.showSelection();
designatorTimeList.showSelection();
setAFOSCommand(selectedNode + selectedCategory
+ selectedDesignator);
} catch (IllegalArgumentException ex) {
designatorList.deselectAll();
designatorTimeList.deselectAll();
setAFOSCommand(selectedNode + selectedCategory);
}
} else {
designatorList.deselectAll();
designatorTimeList.deselectAll();
@ -851,6 +1031,11 @@ public class AfosBrowserDlg extends CaveSWTDialog implements
checkLoadBtn();
}
/**
* Change the designators selected entry and perform updates to the GUI.
*
* @param index
*/
private void selectDisplay(int index) {
String designator = null;
String display = null;
@ -874,6 +1059,10 @@ public class AfosBrowserDlg extends CaveSWTDialog implements
checkLoadBtn();
}
/**
* Check the selected designator and determine if the load buttons should be
* enabled.
*/
private void checkLoadBtn() {
boolean enabled = false;
int designatorIndex = designatorTimeList.getSelectionIndex();
@ -881,7 +1070,8 @@ public class AfosBrowserDlg extends CaveSWTDialog implements
if (designatorIndex >= 0) {
String time = designatorTimeList.getItem(designatorIndex);
if (time.length() > 0) {
enabled = !time.equals("ERROR") && !time.equals("NO DATA");
enabled = !(time.equals(DATA_ERROR) || time.equals(DATA_NONE) || time
.equals(DATA_LOADING));
} else if (displayIndex >= 0) {
enabled = displayList.getItem(displayIndex).length() > 0;
}
@ -892,6 +1082,11 @@ public class AfosBrowserDlg extends CaveSWTDialog implements
setLoadBtnEnabled(enabled);
}
/**
* Reset the a list's selected entries based on its data boolean array.
*
* @param type
*/
private void resetSelection(ListType type) {
List list = null;
@ -929,6 +1124,12 @@ public class AfosBrowserDlg extends CaveSWTDialog implements
}
}
/**
* Display a help dialog for the visible entries of the desired list.
*
* @param type
* @param list
*/
private void displayHelpList(ListType type, List list) {
int height = list.getClientArea().height;
String[] items = list.getItems();
@ -1006,6 +1207,14 @@ public class AfosBrowserDlg extends CaveSWTDialog implements
}
}
/**
* Popup a help menu for the desire item in the list based on the type of
* the list.
*
* @param type
* @param list
* @param index
*/
private void displayHelpText(ListType type, List list, final int index) {
IAction action = null;
@ -1070,6 +1279,13 @@ public class AfosBrowserDlg extends CaveSWTDialog implements
}
}
/**
* Based on the moust click either select the desired item in the list
* populating lists impacted by the selection or display help for the item.
*
* @param type
* @param index
*/
private void selectListItem(ListType type, int index) {
List list = null;
switch (type) {
@ -1131,6 +1347,11 @@ public class AfosBrowserDlg extends CaveSWTDialog implements
}
}
/**
* Set the AFOS Cmd in the parent dialog.
*
* @param command
*/
private void setAFOSCommand(String command) {
// save off command so whenever load and continue is used, the current
// selected command is executed
@ -1138,6 +1359,9 @@ public class AfosBrowserDlg extends CaveSWTDialog implements
callbackClient.setAfosCmdField(currentAfosCommand);
}
/*
* Selection handler for all lists.
*/
private class ListSelectionHandler extends SelectionAdapter {
private final ListType type;
@ -1157,13 +1381,12 @@ public class AfosBrowserDlg extends CaveSWTDialog implements
}
}
/*
* Mouse adaptor for all lists.
*/
private class ListMouseHandler extends MouseAdapter {
final private ListType type;
int previousOffset = -Integer.MAX_VALUE;
int previousIndex = -1;
public ListMouseHandler(ListType type) {
this.type = type;
}
@ -1179,29 +1402,6 @@ public class AfosBrowserDlg extends CaveSWTDialog implements
if (e.button == 2) {
resetSelection(type);
} else {
// List list = (List) e.getSource();
// int index = list.getSelectionIndex();
// int offset = list.getVerticalBar().getSelection() + e.y;
//
// boolean clickedOffList = isOffListClick(e);
//
// // only care about button 1 in case of same indexes where we
// // need to select last item in list instead
// if (e.button == 1) {
// if (clickedOffList) {
// // select last item
// selectListItem(type, list.getItemCount() - 1);
// }
// } else {
// // button 3
// if (!clickedOffList) {
// displayHelpText(type, list, index);
// resetSelection(type);
// }
// }
//
// previousIndex = list.getSelectionIndex();
// previousOffset = offset;
leftMouse = false;
rightMouse = false;
if (e.button == 1) {
@ -1211,23 +1411,12 @@ public class AfosBrowserDlg extends CaveSWTDialog implements
}
}
}
private boolean isOffListClick(MouseEvent e) {
List list = (List) e.getSource();
int index = list.getSelectionIndex();
int offset = list.getVerticalBar().getSelection() + e.y;
if (index == previousIndex
&& index >= 0
&& Math.abs(offset - previousOffset) >= list
.getItemHeight()) {
return true;
}
return false;
}
}
/*
* This handles keeping the two designator lists and the their one scroll
* bar in sync.
*/
private class DesignatorMouseWheelHandler implements MouseWheelListener {
@Override
@ -1255,4 +1444,141 @@ public class AfosBrowserDlg extends CaveSWTDialog implements
}
}
/*
* Job to query for designator times.
*/
private class QueryRequests extends Job {
private final int MAX_PRODUCTS_PER_QUERY = 25;
private TextDBQuery request = null;
private boolean canceled = false;
private java.util.List<String> productIds;
public QueryRequests() {
super("QueryRequests");
setSystem(true);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.runtime.jobs.Job#run(org.eclipse.core.runtime.
* IProgressMonitor)
*/
@Override
protected IStatus run(IProgressMonitor monitor) {
java.util.List<String> prodIds = null;
synchronized (this) {
if (monitor.isCanceled()) {
return Status.OK_STATUS;
} else {
prodIds = productIds;
productIds = null;
}
}
VizApp.runAsync(new Runnable() {
@Override
public void run() {
startDesignatorTimeList();
}
});
int cnt = 0;
Iterator<String> iterator = prodIds.iterator();
while (iterator.hasNext()) {
String productId = iterator.next();
if (canceled) {
synchronized (this) {
canceled = false;
this.notify();
return Status.OK_STATUS;
}
}
request.addProductId(productId);
++cnt;
if (cnt >= MAX_PRODUCTS_PER_QUERY || !iterator.hasNext()) {
final Message queryResponse = request.executeQuery();
if (!canceled) {
VizApp.runAsync(new Runnable() {
@Override
public void run() {
if (!canceled) {
updateAfterQuery(queryResponse);
}
}
});
}
request.clearProductIds();
cnt = 0;
}
}
synchronized (this) {
request = null;
}
VizApp.runAsync(new Runnable() {
@Override
public void run() {
finishDesignatorTimeList();
}
});
return Status.OK_STATUS;
}
/**
* Prepare to process the request for the list of product IDs. If needed
* cancel any active query before scheduling this request.
*
* @param request
* - Query to run.
* @param productIds
* - List of products for the query.
*/
public void addRequest(TextDBQuery request,
java.util.List<String> productIds) {
synchronized (this) {
if (this.request != null) {
if (getState() != Job.NONE) {
cancel();
while (request != null && getState() != Job.NONE) {
try {
wait(100L);
} catch (InterruptedException e) {
AfosBrowserDlg.statusHandler.handle(
Priority.PROBLEM,
e.getLocalizedMessage(), e);
}
}
}
}
this.request = request;
this.productIds = productIds;
schedule();
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.core.runtime.jobs.Job#canceling()
*/
@Override
protected void canceling() {
canceled = true;
}
}
}

View file

@ -29,7 +29,7 @@ import com.raytheon.uf.common.message.Message;
import com.raytheon.uf.common.message.Property;
/**
* TODO Add Description
* Query for text products based on desired desired criteria.
*
* <pre>
*
@ -39,6 +39,7 @@ import com.raytheon.uf.common.message.Property;
* Nov 3, 2008 jkorman Initial creation
* 28May2010 cjeanbap Added operational functionality.
* 02Aug2010 2187 cjeanbap Update variable/method signature to be consistent.
* 22Jan2013 1496 rferrel Added method clearProductIds
*
* </pre>
*
@ -75,7 +76,7 @@ public class TextDBQuery {
private String queryNnnXxx = null;
private String queryFullDataRead = null;
private String queryOperationalMode = null;
// Text product to save.
@ -187,6 +188,16 @@ public class TextDBQuery {
productIds.add(productId);
}
/**
* Remove current productIds. This enables the reuse of query when only the
* productIds change. This allows a Job to break up a large product id list
* into chunks so it can check back with the UI thread to continue or cancel
* doing more queries.
*/
public void clearProductIds() {
productIds = null;
}
/**
*
* @return the queryAfosCmd
@ -310,15 +321,16 @@ public class TextDBQuery {
public void setQueryFullDataRead(String queryFullDataRead) {
this.queryFullDataRead = queryFullDataRead;
}
public String getQueryOperationalModeFlag() {
return queryOperationalMode;
}
/**
* Set the current mode of CAVE, operational/test or practice.
*
* @param operationalMode true or false as a string representation.
* @param operationalMode
* true or false as a string representation.
*/
public void setQueryOperationalMode(String operationalMode) {
this.queryOperationalMode = operationalMode;