Commit 9d4d50a7 authored by hrchilds's avatar hrchilds

Update from January 17, 2006

git-svn-id: http://visit.ilight.com/svn/visit/trunk/src@599 18c085ea-50e0-402c-830e-de6fd14e8384
parent 195b558b
......@@ -14,6 +14,7 @@
#include <visit-config.h>
#include <ParentProcess.h>
#include <DebugStream.h>
#include <SocketConnection.h>
#include <CommunicationHeader.h>
#include <CouldNotConnectException.h>
......@@ -203,21 +204,38 @@ ParentProcess::SetVersion(const std::string &ver)
// I added numRead and numWrite so we don't have to get the number of
// connections to create from the command line anymore.
//
// Brad Whitlock, Tue Jan 17 14:26:09 PST 2006
// Added debug logging.
//
// ****************************************************************************
void
ParentProcess::Connect(int numRead, int numWrite, int *argc, char **argv[],
bool createSockets, int failCode)
{
const char *mName = "ParentProcess::Connect: ";
char **argv2 = *argv;
bool rhostSpecified = false;
bool nWriteSpecified = false, nReadSpecified = false;
int deleteCount = 0, port = 0;
int i, deleteCount = 0, port = 0;
// Log the arguments.
debug5 << mName << "Called with (numRead=" << numRead
<< ", numWrite=, " << numWrite
<< ", argc=" << *argc
<< ", argv={";
for (i = 0; i < *argc ; ++i)
{
debug5 << argv2[i];
if(i < *argc-1)
debug5 << ", ";
}
debug5 << "})" << endl;
//
// Go through the arguments and override the defaults.
//
for (int i = 1; i < *argc ; ++i)
for (i = 1; i < *argc ; ++i)
{
deleteCount = 0;
if (std::string(argv2[i]) == std::string("-host"))
......@@ -226,6 +244,7 @@ ParentProcess::Connect(int numRead, int numWrite, int *argc, char **argv[],
{
rhostSpecified = true;
hostName = std::string(argv2[i + 1]);
debug5 << mName << "hostName = " << hostName.c_str() << endl;
GetHostInfo();
deleteCount = 2;
}
......@@ -235,6 +254,7 @@ ParentProcess::Connect(int numRead, int numWrite, int *argc, char **argv[],
if(rhostSpecified && (i + 1 < *argc))
{
port = atoi(argv2[i + 1]);
debug5 << mName << "port = " << port << endl;
deleteCount = 2;
}
}
......@@ -243,6 +263,7 @@ ParentProcess::Connect(int numRead, int numWrite, int *argc, char **argv[],
if(i + 1 < *argc)
{
securityKey = std::string(argv2[i + 1]);
debug5 << mName << "securityKey = " << securityKey.c_str() << endl;
deleteCount = 2;
}
}
......@@ -272,8 +293,10 @@ ParentProcess::Connect(int numRead, int numWrite, int *argc, char **argv[],
//
if(rhostSpecified && createSockets)
{
debug5 << mName << "Creating sockets" << endl;
if(numRead > 0)
{
debug5 << mName << "Creating read sockets" << endl;
nReadSpecified = true;
writeConnections = new Connection*[numRead];
for(int j = 0; j < numRead; ++j)
......@@ -289,6 +312,7 @@ ParentProcess::Connect(int numRead, int numWrite, int *argc, char **argv[],
if(numWrite > 0)
{
debug5 << mName << "Creating write sockets" << endl;
nWriteSpecified = true;
readConnections = new Connection*[numWrite];
for(int j = 0; j < numWrite; ++j)
......@@ -317,9 +341,12 @@ ParentProcess::Connect(int numRead, int numWrite, int *argc, char **argv[],
// Now that the sockets are open, exchange type representation info
// and set that info in the socket connections.
//
debug5 << mName << "Exchanging type representations." << endl;
ExchangeTypeRepresentations(failCode);
}
}
debug5 << mName << "done" << endl;
}
// ****************************************************************************
......@@ -538,11 +565,15 @@ ParentProcess::GetWriteConnection(int i) const
// Brad Whitlock, Tue Mar 19 16:09:30 PST 2002
// Made it work on Windows.
//
// Brad Whitlock, Tue Jan 17 14:37:35 PST 2006
// Added debug logging.
//
// ****************************************************************************
int
ParentProcess::GetClientSocketDescriptor(int port)
{
const char *mName = "ParentProcess::GetClientSocketDescriptor: ";
int s;
struct hostent *hp;
struct sockaddr_in server;
......@@ -550,6 +581,7 @@ ParentProcess::GetClientSocketDescriptor(int port)
//
// Set up the structures for opening the sockets.
//
debug5 << mName << "Set up using port " << port << endl;
hp = (struct hostent *)hostInfo;
if (hp == NULL)
return -1;
......@@ -561,6 +593,7 @@ ParentProcess::GetClientSocketDescriptor(int port)
//
// Create a socket.
//
debug5 << mName << "Creating a socket" << endl;
s = socket(AF_INET, SOCK_STREAM, 0);
if (s < 0)
{
......@@ -568,14 +601,17 @@ ParentProcess::GetClientSocketDescriptor(int port)
}
// Disable the Nagle algorithm
debug5 << mName << "Setting socket options" << endl;
int opt = 1;
#if defined(_WIN32)
setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (const char FAR *)&opt, sizeof(int));
#else
setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(int));
#endif
debug5 << mName << "Calling connect" << endl;
if (connect(s, (struct sockaddr *)&server, sizeof(server)) < 0)
{
debug5 << mName << "Could not connect!" << endl;
#if defined(_WIN32)
closesocket(s);
#else
......@@ -584,6 +620,8 @@ ParentProcess::GetClientSocketDescriptor(int port)
return -1;
}
debug5 << mName << "Connected socket" << endl;
return s;
}
......@@ -605,6 +643,9 @@ ParentProcess::GetClientSocketDescriptor(int port)
void
ParentProcess::GetHostInfo()
{
debug5 << "ParentProcess::GetHostInfo: Calling gethostbyname(\""
<< hostName.c_str() << "\")\n";
hostInfo = (void *)gethostbyname(hostName.c_str());
}
......@@ -620,7 +661,9 @@ ParentProcess::GetHostInfo()
// Creation: Wed Jan 11 17:02:38 PST 2006
//
// Modifications:
//
// Brad Whitlock, Tue Jan 17 14:38:35 PST 2006
// Added debug logging.
//
// ****************************************************************************
const std::string &
......@@ -631,16 +674,18 @@ ParentProcess::GetLocalUserName()
//
if(localUserName.size() == 0)
{
debug5 << "Getting local user name: ";
#if defined(_WIN32)
char username[100];
DWORD maxLen = 100;
GetUserName((LPTSTR)username, (LPDWORD)&maxLen);
localUserName = std::string(username);
char username[100];
DWORD maxLen = 100;
GetUserName((LPTSTR)username, (LPDWORD)&maxLen);
localUserName = std::string(username);
#else
struct passwd *users_passwd_entry = NULL;
if((users_passwd_entry = getpwuid(getuid())) != NULL)
localUserName = std::string(users_passwd_entry->pw_name);
struct passwd *users_passwd_entry = NULL;
if((users_passwd_entry = getpwuid(getuid())) != NULL)
localUserName = std::string(users_passwd_entry->pw_name);
#endif
debug5 << localUserName << endl;
}
return localUserName;
......
This diff is collapsed.
......@@ -251,6 +251,10 @@ ColorTableManager::ImportHelper(void *data, const std::string &ctFileName,
// Brad Whitlock, Fri Jul 11 15:44:40 PST 2003
// Fixed so it works on Windows.
//
// Brad Whitlock, Tue Jan 17 11:17:09 PDT 2006
// I added code to prevent the file path from being added to the color
// table name.
//
// ****************************************************************************
void
......@@ -266,11 +270,19 @@ ColorTableManager::ImportColorTable(const std::string &ctFileName)
if(node != 0)
{
debug4 << "Imported color table " << ctFileName.c_str() << endl;
std::string ctName;
std::string::size_type pos = ctFileName.rfind(SLASH_STRING);
if(pos == std::string::npos)
ctName = ctFileName;
else
ctName = ctFileName.substr(pos + 1, ctFileName.size() - pos - 1 - 3);
debug4 << "Imported color table " << ctFileName.c_str() << " as "
<< ctName.c_str() << endl;
ColorControlPointList ccpl2;
ccpl2.SetFromNode(node);
ccpl2.SetExternalFlag(true);
ctAtts->AddColorTable(ctFileName, ccpl2);
ctAtts->AddColorTable(ctName, ccpl2);
delete node;
}
else
......
......@@ -853,6 +853,11 @@ avtContourFilter::CreatePercentValues(double mn, double mx)
// Change the way the levels are set when the user specifies the number
// of levels and the minimum and maximum.
//
// Brad Whitlock, Mon Dec 19 17:17:05 PST 2005
// I changed the code so it conditionally applies the extrema offset
// because applying it when min/max were set made it impossible to get
// contours that go through the min/max values.
//
// ****************************************************************************
void
......@@ -892,14 +897,13 @@ avtContourFilter::CreateNIsoValues(double min, double max)
//
// If we have to generate the isolevels, then we want them to be offset
// at the extrema. This offset is arbitrary and mimicks what MeshTV did,
// except in the case where the minimum and maximum are specified. In
// MeshTV, the offsets weren't applied if the minimum or maximum were
// specified, whereas here we always apply the offsets.
// except in the case where the minimum and maximum are specified.
//
extremaOffset = (hi - lo) / (nLevels + 1.);
lo += extremaOffset;
hi -= extremaOffset;
if(!atts.GetMinFlag())
lo += extremaOffset;
if(!atts.GetMaxFlag())
hi -= extremaOffset;
if (nLevels <= 1)
{
......
#include <QvisColorTableButton.h>
#include <qpopupmenu.h>
#include <qapplication.h>
#include <qtooltip.h>
//
// Static members.
......@@ -162,6 +163,8 @@ QvisColorTableButton::sizePolicy() const
// Creation: Sat Jun 16 20:08:42 PST 2001
//
// Modifications:
// Brad Whitlock, Tue Jan 17 11:41:44 PDT 2006
// Added a tooltip so long color table names can be put in a tooltip.
//
// ****************************************************************************
......@@ -170,6 +173,7 @@ QvisColorTableButton::useDefaultColorTable()
{
colorTable = QString("Default");
setText(colorTable);
QToolTip::add(this, colorTable);
}
// ****************************************************************************
......@@ -188,6 +192,9 @@ QvisColorTableButton::useDefaultColorTable()
// Brad Whitlock, Fri Feb 15 10:15:43 PDT 2002
// Made it set the menu text to "Default" if no color table is found.
//
// Brad Whitlock, Tue Jan 17 11:41:44 PDT 2006
// Added a tooltip so long color table names can be put in a tooltip.
//
// ****************************************************************************
void
......@@ -197,9 +204,14 @@ QvisColorTableButton::setColorTable(const QString &ctName)
{
colorTable = ctName;
setText(colorTable);
QToolTip::add(this, colorTable);
}
else
setText(QString("Default"));
{
QString def("Default");
setText(def);
QToolTip::add(this, def);
}
}
// ****************************************************************************
......@@ -305,6 +317,8 @@ QvisColorTableButton::popupPressed()
// Creation: Sat Jun 16 20:11:06 PST 2001
//
// Modifications:
// Brad Whitlock, Tue Jan 17 11:41:44 PDT 2006
// Added a tooltip so long color table names can be put in a tooltip.
//
// ****************************************************************************
......@@ -313,13 +327,16 @@ QvisColorTableButton::colorTableSelected(int index)
{
if(index == 0)
{
emit selectedColorTable(true, QString("Default"));
setText("Default");
QString def("Default");
emit selectedColorTable(true, def);
setText(def);
QToolTip::add(this, def);
}
else if(index < numColorTableNames + 2)
{
emit selectedColorTable(false, colorTableNames[index-2]);
setText(colorTableNames[index-2]);
QToolTip::add(this, colorTableNames[index-2]);
}
}
......
......@@ -2086,6 +2086,7 @@ MDServerConnection::GetFilteredFileList(GetFileListRPC::FileList &files)
// to the map.
std::string key(path + rootName);
virtualFiles[key].path = path;
virtualFiles[key].filterList = filterList;
virtualFiles[key].files.swap(pos->second.files);
}
}
......@@ -2355,27 +2356,35 @@ MDServerConnection::ConsolidateVirtualDatabases(
// and file grouping settings that were in place the last time we read
// the directory.
//
// Brad Whitlock, Tue Jan 17 16:35:40 PST 2006
// I added another case that allows us to update a virtual database that
// we've seen before.
//
// ****************************************************************************
const MDServerConnection::VirtualFileInformationMap::iterator
MDServerConnection::GetVirtualFileDefinition(const std::string &file)
{
const char *mName = "MDServerConnection::GetVirtualFileDefinition: ";
// Look for the file in the virtual files map.
VirtualFileInformationMap::iterator virtualFile = virtualFiles.find(file);
//
// If the file was not found in the virtual file map, but it contains
// a wildcard character, which means that it is a virtual file, read
// the file list to try and create a definition for the virtual file
// so we can open it even if we've never seen it before.
//
if (virtualFile == virtualFiles.end() &&
file.find("*") != std::string::npos)
bool fileContainsStar = (file.find("*") != std::string::npos);
std::string::size_type index = file.rfind(SLASH_STRING);
if (virtualFile == virtualFiles.end())
{
int index = file.rfind(SLASH_STRING);
if(index != std::string::npos)
//
// If the file was not found in the virtual file map, but it contains
// a wildcard character, which means that it is a virtual file, read
// the file list to try and create a definition for the virtual file
// so we can open it even if we've never seen it before.
//
if(fileContainsStar && index != std::string::npos)
{
debug2 << "A virtual database was requested but we've never seen "
debug2 << mName << "A virtual database (" << file.c_str()
<< ") was requested but we've never seen "
"it before. Try and get a definition for it." << endl;
// Remember the old path.
......@@ -2397,6 +2406,43 @@ MDServerConnection::GetVirtualFileDefinition(const std::string &file)
virtualFile = virtualFiles.find(file);
}
}
else if(virtualFile->second.files.size() == 0 &&
fileContainsStar && index != std::string::npos)
{
debug2 << mName << "A virtual database (" << file.c_str()
<< ") was requested and we've seen "
"it before but it was closed and its definition "
"(list of files) was erased. Try and re-read its "
"definition using the filter that we've saved for it (";
for(int i = 0; i < virtualFile->second.filterList.size(); ++i)
{
debug2 << virtualFile->second.filterList[i].c_str();
if(i < virtualFile->second.filterList.size()-1)
debug2 << ", ";
}
debug2 << ")." << endl;
// Remember the old path.
std::string oldPath(currentWorkingDirectory);
// We found the last separator so we can change to that path
// to ensure that the file list is read.
std::string path(file.substr(0, index));
ChangeDirectory(path);
// Get the filtered file list. This creates virtual files.
GetFileListRPC::FileList f;
stringVector oldFilterList(filterList);
filterList = virtualFile->second.filterList;
GetFilteredFileList(f);
filterList = oldFilterList;
// Change the path back to the old path.
ChangeDirectory(oldPath);
// Look for the file again in the virtual file map.
virtualFile = virtualFiles.find(file);
}
return virtualFile;
}
......@@ -2620,11 +2666,18 @@ MDServerConnection::GetDatabase(string file, int timeState,
// I added a db argument so this rpc can be used to remove a virtual file
// definition without necessarily having to close the database.
//
// Brad Whitlock, Tue Jan 17 16:37:18 PST 2006
// Changed the method so virtual databases are "deleted" from the map by
// deleting their list of files. This way, other information such as the
// filter is preserved so we can reliably recreate the list of files later,
// if needed.
//
// ****************************************************************************
void
MDServerConnection::CloseDatabase(const std::string &db)
{
const char *mName = "MDServerConnection::CloseDatabase: ";
std::string dbToClose(db);
bool closeCurrentDB = (dbToClose == currentDatabaseName);
if(dbToClose == "")
......@@ -2637,14 +2690,15 @@ MDServerConnection::CloseDatabase(const std::string &db)
if(virtualFile != virtualFiles.end())
{
debug1 << "Removing " << dbToClose.c_str()
<< " from the virtual file map." << endl;
virtualFiles.erase(virtualFile);
debug1 << mName << "Clearing out " << dbToClose.c_str()
<< "'s file list from the virtual file map so we can "
"repopulate it later." << endl;
virtualFile->second.files.clear();
}
if (closeCurrentDB && currentDatabase != NULL)
{
debug1 << "Closing database: " << currentDatabaseName.c_str() << endl;
debug1 << mName << "Closing database: " << currentDatabaseName.c_str() << endl;
delete currentDatabase;
currentDatabase = NULL;
currentDatabaseName = "";
......
......@@ -128,6 +128,11 @@ class Xfer;
// Brad Whitlock, Wed Dec 14 16:58:24 PST 2005
// Added ReadFileListAttributes.
//
// Brad Whitlock, Tue Jan 17 17:05:59 PST 2006
// I changed VirtualFileInformation so the filter used when we create a
// virtual database is stored along with the definition in case we have to
// reread the definition later.
//
// ****************************************************************************
class MDServerConnection
......@@ -157,6 +162,7 @@ class MDServerConnection
std::string path;
stringVector files;
int digitLength;
stringVector filterList;
};
typedef std::map<VirtualFileName, VirtualFileInformation> VirtualFileInformationMap;
......
......@@ -730,43 +730,3 @@ LineoutListItem::SetLineoutsFollowTime(bool newMode)
queries[i]->SetFollowsTime(newMode);
}
// ****************************************************************************
// Method: LineoutListItem::SetTimeSlider
//
// Purpose:
// Creates or removes time slider for the plot list in the results window.
//
// Programmer: Kathleen Bonnell
// Creation: February 3, 2005
//
// ****************************************************************************
void
LineoutListItem::SetTimeSlider(bool removeSlider)
{
ViewerPlotList *resList = resWin->GetPlotList();
if (removeSlider)
{
if (resList->HasActiveTimeSlider())
resList->DeleteTimeSlider(resList->GetActiveTimeSlider());
}
else
{
ViewerPlotList *origList = origWin->GetPlotList();
if (origList->HasActiveTimeSlider())
{
const std::string &ats = origList->GetActiveTimeSlider();
int state, nStates;
origList->GetTimeSliderStates(ats, state, nStates);
resList->CreateTimeSlider(ats, state);
resList->SetActiveTimeSlider(ats);
ViewerWindowManager::Instance()->UpdateWindowInformation(
WINDOWINFO_TIMESLIDERS, resWin->GetWindowId());
}
}
}
......@@ -42,6 +42,10 @@ class avtToolInterface;
// Kathleen Bonnell, Thu Feb 3 16:27:10 PST 2005
// Added SetLineoutsFollowTime, SetTimeSlider.
//
// Kathleen Bonnell, Tue Jan 17 11:30:15 PST 2006
// Removed SetTimeSlider.
//
//
// ****************************************************************************
class VIEWER_API LineoutListItem : public SimpleObserver
......@@ -77,8 +81,6 @@ class VIEWER_API LineoutListItem : public SimpleObserver
void DisableTool(void);
void ViewDimChanged(void);
void SetLineoutsFollowTime(bool);
void SetTimeSlider(bool);
private:
ViewerPlot *origPlot;
......
......@@ -703,6 +703,9 @@ SaveViewAction::ChoiceEnabled(int i) const
// Brad Whitlock, Thu Dec 18 13:35:10 PST 2003
// Added another argument to the view objects's CreateNode methods.
//
// Brad Whitlock, Tue Jan 17 10:52:08 PDT 2006
// I made the saved views contain all of their fields no matter what.
//
// ****************************************************************************
bool
......@@ -725,7 +728,7 @@ SaveViewAction::CreateNode(DataNode *parentNode)
avtViewCurve *v = (avtViewCurve *)views[i].view;
v->SetToViewCurveAttributes(&viewAtts);
if(viewAtts.CreateNode(saveviewNode, false, false))
if(viewAtts.CreateNode(saveviewNode, true, false))
{
haveViews = true;
viewTypes.push_back(views[i].viewType);
......@@ -738,7 +741,7 @@ SaveViewAction::CreateNode(DataNode *parentNode)
avtView2D *v = (avtView2D *)views[i].view;
v->SetToView2DAttributes(&viewAtts);
if(viewAtts.CreateNode(saveviewNode, false, false))
if(viewAtts.CreateNode(saveviewNode, true, false))
{
haveViews = true;
viewTypes.push_back(views[i].viewType);
......@@ -751,7 +754,7 @@ SaveViewAction::CreateNode(DataNode *parentNode)
avtView3D *v = (avtView3D *)views[i].view;
v->SetToView3DAttributes(&viewAtts);
if(viewAtts.CreateNode(saveviewNode, false, false))
if(viewAtts.CreateNode(saveviewNode, true, false))
{
haveViews = true;
viewTypes.push_back(views[i].viewType);
......
......@@ -5031,7 +5031,9 @@ ViewerPlotList::DemoteOperator(int operatorId, bool applyToAll)
// Creation: Thu Apr 10 10:10:37 PDT 2003
//
// Modifications:
//
// Brad Whitlock, Tue Jan 17 12:08:44 PDT 2006
// Added a line of code to update the vis window.
//
// ****************************************************************************
void
......@@ -5062,6 +5064,11 @@ ViewerPlotList::RemoveOperator(int operatorId, bool applyToAll)
//
UpdatePlotList();
UpdatePlotAtts(false);
//
// Update the frame
//
UpdateFrame();
}
}
......
......@@ -468,6 +468,9 @@ ViewerQueryManager::AddQuery(ViewerWindow *origWin, Line *lineAtts,
// Tell the lineouts whether or not to follow time, and whether or not to
// use a time slider.
//
// Kathleen Bonnell, Tue Jan 17 11:30:15 PST 2006
// Removed call to SetTimeSlider.
//
// ****************************************************************************
void
......@@ -540,11 +543,6 @@ ViewerQueryManager::SimpleAddQuery(ViewerQuery_p query, ViewerPlot *oplot,
//
lineoutList[index]->AddQuery(query);
//
// Set the on/off state of the time slider
//
lineoutList[index]->SetTimeSlider(gla->GetDynamic());
//
// Tell it whether or not to follow time.
//
......@@ -2535,6 +2533,9 @@ ViewerQueryManager::SetDynamicLineout(bool newMode)
// Use new GlobalLineout atts to set flags for lineouts, for following time,
// and using a time slider.
//
// Kathleen Bonnell, Tue Jan 17 11:30:15 PST 2006
// Removed call to SetLineoutsTimeSlider.
//
// ****************************************************************************
void
......@@ -2553,7 +2554,6 @@ ViewerQueryManager::SetGlobalLineoutAttsFromClient()
if (globalLineoutAtts->GetDynamic() != goingDynamic)
{
SetDynamicLineout(goingDynamic);
SetLineoutsTimeSlider(goingDynamic);
SetLineoutsFollowTime(!(goingDynamic && creatingCurve));
}
else if (globalLineoutAtts->GetCurveOption() !=
......@@ -4415,31 +4415,6 @@ ViewerQueryManager::SetLineoutsFollowTime(bool followTime)
}
// ****************************************************************************
// Method: ViewerQueryManager::SetLineoutsTimeSlider
//
// Purpose:
// Tells the lineout lists to turn on/off the time slider for the
// reswin's plot list.
//
// Arguments:
// removeTimeSlider True if time slider should be removed, false otherwise.
//
// Programmer: Kathleen Bonnell
// Creation: Februrary 3, 2005
//
// ****************************************************************************
void
ViewerQueryManager::SetLineoutsTimeSlider(bool removeTimeSlider)
{
for (int i = 0; i < nLineouts; ++i)
{
lineoutList[i]->SetTimeSlider(removeTimeSlider);
}
}
// ****************************************************************************
// Method: ViewerQueryManager::ClearRefLines
//
......
......@@ -177,6 +177,9 @@ typedef struct {
// Kathleen Bonnell, Tue Aug 16 10:03:27 PDT 2005
// Changed arg from ViewerWindow to ViewerPlot for EngineExistsForQuery.
//
// Kathleen Bonnell, Tue Jan 17 11:30:15 PST 2006
// Removed SetLineoutsTimeSlider.
//
// ****************************************************************************
class VIEWER_API ViewerQueryManager
......@@ -306,7 +309,6 @@ class VIEWER_API ViewerQueryManager
void ResetLineoutCache();
void SetDynamicLineout(bool);
void SetLineoutsFollowTime(bool);
void SetLineoutsTimeSlider(bool);
void HandlePickCache();
bool initialPick;
......
......@@ -1129,13 +1129,17 @@ VariableMenuPopulator::VariableList::Size() const
// Brad Whitlock, Thu Aug 18 15:55:19 PST 2005
// Fixed on win32.
//
// Mark C. Miller, Tue Jan 17 18:18:17 PST 2006
// Applied patch from Paul Selby of Wed Dec 14 13:27:45 GMT 2005
// so that it will group variables in top level of path.
//
// ****************************************************************************
bool
VariableMenuPopulator::VariableList::IsGroupingRequired(