Commit fcfa3023 authored by Aaron Bray's avatar Aaron Bray

Data Requests are looking better, still need to add support for all types, but...

Data Requests are looking better, still need to add support for all types, but things are working well
parent 62cc90f2
......@@ -80,7 +80,7 @@ if(NOT Pulse_FOUND)
#GIT_TAG a8e9ac38f121fe9e64a1fff7860e1b19
#GIT_SHALLOW 1
URL https://gitlab.kitware.com/physiology/engine/-/archive/REL_2_1_0/engine-REL_2_1_0.zip
URL_MD5 f56c86e7ae82a41e9a22776774525898
URL_MD5 29d0e8729d45de2d72218d4bcabe33b5ee0af738
BINARY_DIR ${CMAKE_BINARY_DIR}/Pulse-build
CMAKE_ARGS
-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}
......
......@@ -3,24 +3,15 @@ See accompanying NOTICE file for details.*/
#include "DataRequestViewWidget.h"
#include "ui_DataRequestView.h"
#include <QList.h>
#include <QLayout>
#include <QMdiArea.h>
#include <QMdiSubWindow>
#include "QPulsePlot.h"
#include "PlotSetWidget.h"
#include "cdm/CommonDataModel.h"
#include "PulsePhysiologyEngine.h"
#include "cdm/engine/SEEngineTracker.h"
#include "cdm/engine/SEDataRequest.h"
#include "cdm/engine/SEDataRequestManager.h"
#include "cdm/substance/SESubstanceManager.h"
#include "cdm/substance/SESubstance.h"
#include "cdm/system/equipment/electrocardiogram/SEElectroCardioGramWaveformInterpolator.h"
#include "cdm/utils/FileUtils.h"
#include "cdm/properties/SEScalarTime.h"
#include "cdm/properties/SEScalarVolume.h"
#include "cdm/properties/SEScalarVolumePerTime.h"
#include "controls/PlotSetWidget.h"
class QDataRequestViewWidget::Controls : public Ui::DataRequestViewWidget
{
......@@ -34,6 +25,10 @@ QDataRequestViewWidget::QDataRequestViewWidget(QPulse& qp, QWidget *parent, Qt::
m_Controls = new Controls(qp);
m_Controls->setupUi(this);
m_Controls->TileButton->setEnabled(false);
m_Controls->NewPlotSetButton->setEnabled(false);
qp.GetEngine().GetEngineTracker()->SetTrackMode(TrackMode::Dynamic);
connect(m_Controls->NewPlotSetButton, SIGNAL(clicked()), SLOT(NewPlotSet()));
connect(m_Controls->TileButton, SIGNAL(clicked()), SLOT(Tile()));
}
......@@ -46,90 +41,23 @@ QDataRequestViewWidget::~QDataRequestViewWidget()
void QDataRequestViewWidget::Reset()
{
}
/*
void QDataRequestViewWidget::BuildGraphs(PhysiologyEngine& pulse)
{
std::stringstream ss;
SEDataRequestManager& drMgr = pulse.GetEngineTracker()->GetDataRequestManager();
std::string title;
std::string unit;
m_Controls->Titles.clear();
if (drMgr.GetDataRequests().empty())
{
// Let's load up some default requests
drMgr.CreatePhysiologyDataRequest("TidalVolume", VolumeUnit::mL);
drMgr.CreatePhysiologyDataRequest("CardiacOutput", VolumePerTimeUnit::L_Per_min);
drMgr.CreateGasCompartmentDataRequest(pulse::PulmonaryCompartment::LeftLung, "Volume", VolumeUnit::mL);
drMgr.CreateGasCompartmentDataRequest(pulse::PulmonaryCompartment::RightLung, "Volume", VolumeUnit::mL);
}
for (SEDataRequest* dr : drMgr.GetDataRequests())
QMdiSubWindow* item;
while ((item = m_Controls->mdiArea->subWindowList().takeAt(0)) != nullptr)
{
m_Controls->Map[dr->GetPropertyName()] = NULL;
m_Controls->LogBox.append(dr->GetPropertyName().c_str());
if (dr->HasUnit())
unit = " (" + dr->GetUnit()->GetString() + ")";
else
unit = "";
switch (dr->GetCategory())
{
case eDataRequest_Category::Patient:
title = "Patient " + dr->GetPropertyName() + unit;
break;
case eDataRequest_Category::Physiology:
title = dr->GetPropertyName() + unit;
break;
case eDataRequest_Category::Environment:
title = dr->GetPropertyName() + unit;
break;
case eDataRequest_Category::GasCompartment:
case eDataRequest_Category::LiquidCompartment:
if (dr->HasSubstanceName())
title = dr->GetCompartmentName() + " " + dr->GetSubstanceName() + " " + dr->GetPropertyName() + unit;
else
title = dr->GetCompartmentName() + " " + dr->GetPropertyName() + unit;
break;
case eDataRequest_Category::ThermalCompartment:
title = dr->GetCompartmentName() + " " + dr->GetPropertyName() + unit;
break;
case eDataRequest_Category::TissueCompartment:
title = dr->GetCompartmentName() + " " + dr->GetPropertyName() + unit;
break;
case eDataRequest_Category::Substance:
if (dr->HasCompartmentName())
title = dr->GetSubstanceName() + " " + dr->GetCompartmentName() + " " + dr->GetPropertyName() + unit;
else
title = dr->GetSubstanceName() + " " + dr->GetPropertyName() + unit;
break;
case eDataRequest_Category::AnesthesiaMachine:
title = dr->GetPropertyName() + unit;
break;
case eDataRequest_Category::ECG:
title = dr->GetPropertyName() + unit;
break;
case eDataRequest_Category::Inhaler:
title = dr->GetPropertyName() + unit;
break;
}
if (!pulse.GetEngineTracker()->TrackRequest(*dr))
{// Could not hook this up, get rid of it
ss << "Unable to find data for " << title;
m_Controls->LogBox.append(ss.str().c_str());
continue;
}
m_Controls->Titles.push_back(dr->GetPropertyName());
QPlotSetWidget* plotSet = (QPlotSetWidget*)item->widget();
plotSet->Reset();
m_Controls->mdiArea->subWindowList().removeAt(0);
}
m_Controls->TileButton->setEnabled(false);
m_Controls->NewPlotSetButton->setEnabled(false);
}
*/
void QDataRequestViewWidget::NewPlotSet()
{
QPlotSetWidget* plotSet = new QPlotSetWidget(m_Controls->Pulse, this);
m_Controls->mdiArea->addSubWindow(plotSet);
m_Controls->mdiArea->tileSubWindows();
plotSet->show();
plotSet->setTitleBarWidget(new QWidget());
m_Controls->mdiArea->addSubWindow(plotSet)->showMaximized();
}
void QDataRequestViewWidget::Tile()
......@@ -139,54 +67,29 @@ void QDataRequestViewWidget::Tile()
void QDataRequestViewWidget::AtSteadyState(PhysiologyEngine& pulse)
{
for (QMdiSubWindow* subwindow : m_Controls->mdiArea->subWindowList())
((QPlotSetWidget*)subwindow->widget())->AtSteadyState(pulse);
}
void QDataRequestViewWidget::AtSteadyStateUpdateUI()
{
m_Controls->TileButton->setEnabled(true);
m_Controls->NewPlotSetButton->setEnabled(true);
for (QMdiSubWindow* subwindow : m_Controls->mdiArea->subWindowList())
((QPlotSetWidget*)subwindow->widget())->AtSteadyStateUpdateUI();
}
void QDataRequestViewWidget::ProcessPhysiology(PhysiologyEngine& pulse)
{// This is called from a thread, you should NOT update UI here
// This is where we pull data from pulse, and push any actions to it
size_t i = 0;
QPulsePlot* plot = nullptr;
pulse.GetEngineTracker()->PullData();
/*double v;
for (SEDataRequest* dr : pulse.GetEngineTracker()->GetDataRequestManager().GetDataRequests())
{
std::string propertyName = dr->GetPropertyName();
for (QMdiSubWindow* subwindow : m_Controls->mdiArea->subWindowList())
{
GraphModal* modal = qobject_cast<GraphModal*>(subwindow->widget());
std::map<std::string, QPulsePlot*> map = modal->getMap();
if (map.find(propertyName) != map.end() && map[propertyName] != nullptr)
{
plot = map[propertyName];
break;
}
}
if (plot == nullptr)
continue;
if (dr->HasUnit())
v = pulse.GetEngineTracker()->GetScalar(*dr)->GetValue(*dr->GetUnit());
else
v = pulse.GetEngineTracker()->GetScalar(*dr)->GetValue();
plot->Append(pulse.GetSimulationTime(TimeUnit::s), v);
}*/
pulse.GetEngineTracker()->TrackData();
for (QMdiSubWindow* subwindow : m_Controls->mdiArea->subWindowList())
((QPlotSetWidget*)subwindow->widget())->ProcessPhysiology(pulse);
}
void QDataRequestViewWidget::PhysiologyUpdateUI()
{
for (QMdiSubWindow* subwindow : m_Controls->mdiArea->subWindowList())
subwindow->widget()->update();
//{
// QPlotSetWidget* plotSet = qobject_cast<QPlotSetWidget*>(subwindow->widget());
// for (QPulsePlot* plot : plotSet->getPlots())
// {
// plot->UpdateUI();
// }
//}
((QPlotSetWidget*)subwindow->widget())->PhysiologyUpdateUI();
}
......@@ -5,6 +5,7 @@ See accompanying NOTICE file for details.*/
#include <QObject>
#include <QDockWidget>
#include "QPulse.h"
#include <set>
namespace Ui {
......@@ -24,10 +25,12 @@ public:
void AtSteadyStateUpdateUI();// Main Window will call this to update UI Components
void ProcessPhysiology(PhysiologyEngine& pulse);
void PhysiologyUpdateUI();// Main Window will call this to update UI Components
signals:
protected slots:
void Tile();
void NewPlotSet();
private:
class Controls;
Controls* m_Controls;
......
This diff is collapsed.
......@@ -18,12 +18,11 @@ public:
QDataRequestWidget(QPulse& qp, QWidget *parent = Q_NULLPTR, Qt::WindowFlags flags = Qt::WindowFlags());
virtual ~QDataRequestWidget();
SEDataRequest* GetDataRequest();
SEDataRequest& GetDataRequest();
signals:
protected slots:
void UpdateSelectionBoxes();
void ControlsToPulse();
private:
class Controls;
......
......@@ -6,30 +6,110 @@ See accompanying NOTICE file for details.*/
#include "QPulsePlot.h"
#include "DataRequestWidget.h"
#include "cdm/CommonDataModel.h"
#include "PulsePhysiologyEngine.h"
#include "cdm/engine/SEEngineTracker.h"
#include "cdm/engine/SEDataRequest.h"
#include "cdm/properties/SEScalarTime.h"
// TODO
// I took this from SEEngineTrack, this method should go in there
// (I did change the delimeter from "-" to " ")
std::string GetTitle(SEDataRequest& dr)
{
std::stringstream ss;
switch (dr.GetCategory())
{
case eDataRequest_Category::Patient:
ss << "Patient";
case eDataRequest_Category::Physiology:
case eDataRequest_Category::Environment:
case eDataRequest_Category::AnesthesiaMachine:
case eDataRequest_Category::ECG:
case eDataRequest_Category::Inhaler:
{
if (!dr.GetUnit())
ss << dr.GetPropertyName();
else
ss << dr.GetPropertyName() << "(" << dr.GetUnit() << ")";
break;
}
case eDataRequest_Category::GasCompartment:
case eDataRequest_Category::LiquidCompartment:
case eDataRequest_Category::ThermalCompartment:
case eDataRequest_Category::TissueCompartment:
{
if (dr.HasSubstanceName())
{
if (!dr.GetUnit())
ss << dr.GetCompartmentName() << " " << dr.GetSubstanceName() << " " << dr.GetPropertyName();
else
ss << dr.GetCompartmentName() << " " << dr.GetSubstanceName() << " " << dr.GetPropertyName() << "(" << dr.GetUnit() << ")";
}
else
{
if (!dr.GetUnit())
ss << dr.GetCompartmentName() << " " << dr.GetPropertyName();
else
ss << dr.GetCompartmentName() << " " << dr.GetPropertyName() << "(" << dr.GetUnit() << ")";
}
break;
}
case eDataRequest_Category::Substance:
{
if (dr.HasCompartmentName())
{
if (!dr.GetUnit())
ss << dr.GetSubstanceName() << " " << dr.GetCompartmentName() << " " << dr.GetPropertyName();
else
ss << dr.GetSubstanceName() << " " << dr.GetCompartmentName() << " " << dr.GetPropertyName() << "(" << dr.GetUnit() << ")";
}
else
{
if (!dr.GetUnit())
ss << dr.GetSubstanceName() << " " << dr.GetPropertyName();
else
ss << dr.GetSubstanceName() << " " << dr.GetPropertyName() << "(" << dr.GetUnit() << ")";
}
break;
}
default:
ss << "Unhandled data request category: " << eDataRequest_Category_Name(dr.GetCategory()) << std::endl;
}
return ss.str();
}
class QPlotSetWidget::Controls : public Ui::PlotSetWidget
{
public:
Controls(QTextEdit& log) : LogBox(log) {}
QTextEdit& LogBox;
QDataRequestWidget* DataRequestWidget;
std::map<std::string, QPulsePlot*> Map;
QTextEdit& LogBox;
QDataRequestWidget* DataRequestWidget;
size_t CurrentPlot = -1;
std::vector<QPulsePlot*> Plots;
std::vector<SEDataRequest*> DataRequests;
};
QPlotSetWidget::QPlotSetWidget(QPulse& qp, QWidget *parent) : QDialog(parent)
QPlotSetWidget::QPlotSetWidget(QPulse& qp, QWidget *parent, Qt::WindowFlags flags) : QDockWidget(parent, flags)
{
m_Controls = new Controls(qp.GetLogBox());
m_Controls->setupUi(this);
m_Controls->DataRequestWidget = new QDataRequestWidget(qp, this);
//m_Controls->DataRequestWidget->raise();
//m_Controls->DataRequestWidget->setVisible(true);
m_Controls->PlotContainer->layout()->addWidget(m_Controls->DataRequestWidget);
m_Controls->DataRequestWidget->setTitleBarWidget(new QWidget());
m_Controls->PlotSetButtons->hide();
m_Controls->DataRequestButtons->show();
m_Controls->DataRequestWidget->show();
m_Controls->PlotComboBox->hide();
connect(m_Controls->PlotComboBox, SIGNAL(currentTextChanged(QString)),SLOT(SwitchPlot()));
connect(m_Controls->PlotComboBox, SIGNAL(currentIndexChanged(int)),SLOT(SwitchPlot()));
connect(m_Controls->AddPlotButton, SIGNAL(clicked()),SLOT(AddPlot()));
connect(m_Controls->RemovePlotButton, SIGNAL(clicked()),SLOT(RemovePlot()));
connect(m_Controls->RemovePlotButton, SIGNAL(clicked()), SLOT(RemovePlot()));
connect(m_Controls->AddDRButton, SIGNAL(clicked()), SLOT(AddDataRequest()));
connect(m_Controls->CancelDRButton, SIGNAL(clicked()), SLOT(CancelDataRequest()));
this->setWindowTitle(QString(""));
}
......@@ -39,41 +119,118 @@ QPlotSetWidget::~QPlotSetWidget()
delete m_Controls;
}
void QPlotSetWidget::Reset()
{
for (QPulsePlot* plot : m_Controls->Plots)
delete plot;
m_Controls->Plots.clear();
m_Controls->DataRequests.clear();
m_Controls->PlotComboBox->clear();
m_Controls->PlotComboBox->hide();
m_Controls->DataRequestWidget->show();
m_Controls->PlotSetButtons->hide();
m_Controls->DataRequestButtons->show();
}
void QPlotSetWidget::AddDataRequest()
{
SEDataRequest& dr = m_Controls->DataRequestWidget->GetDataRequest();
QString title = GetTitle(dr).c_str();
int idx=-1;
for(; idx<m_Controls->Plots.size(); idx++)
if (m_Controls->Plots[idx]->GetChart().title() == title)
break;
if (idx == -1)
{
idx = (int)m_Controls->Plots.size();
QPulsePlot* newPlot = new QPulsePlot(1000);
m_Controls->Plots.push_back(newPlot);
m_Controls->DataRequests.push_back(&dr);
newPlot->GetChart().setTitle(dr.GetPropertyName().c_str());
m_Controls->PlotComboBox->addItem(title);
m_Controls->PlotContainer->layout()->addWidget(&newPlot->GetView());
}
// Update Controls
m_Controls->PlotComboBox->show();
m_Controls->PlotComboBox->setCurrentIndex(idx);
m_Controls->DataRequestWidget->hide();
m_Controls->PlotSetButtons->show();
m_Controls->DataRequestButtons->hide();
}
void QPlotSetWidget::CancelDataRequest()
{
m_Controls->DataRequestWidget->hide();
m_Controls->PlotSetButtons->show();
m_Controls->DataRequestButtons->hide();
}
void QPlotSetWidget::AddPlot()
{
//Popopen DR here, and get resulting DR propertyName
//std::string property = dr->GetPropertyName();
std::string property = "CardiacOutput";
QPulsePlot* newPlot = new QPulsePlot(1000);
m_Controls->Map[property] = newPlot;
newPlot->GetChart().setTitle(property.c_str());
m_Controls->PlotComboBox->addItem(QString(property.c_str()));
m_Controls->PlotComboBox->hide();
m_Controls->DataRequestWidget->show();
m_Controls->PlotSetButtons->hide();
m_Controls->DataRequestButtons->show();
for (QPulsePlot* plot : m_Controls->Plots)
plot->GetView().hide();
}
void QPlotSetWidget::RemovePlot()
{
//if (m_Controls->GraphProperty->count() < 0)
// return false;
//std::string property = m_Controls->GraphProperty->currentText().toStdString();
//m_Controls->DataGraphWidget->layout()->removeWidget(&m_Controls->currPlot->GetView());
//m_Controls->currPlot->GetView().hide();
//m_Controls->GraphProperty->removeItem(m_Controls->GraphProperty->currentIndex());
//delete m_Controls->currPlot;
//m_Controls->currPlot = nullptr;
//m_Controls->Map.erase(property);
//SwitchPlot();
int idx = m_Controls->PlotComboBox->currentIndex();
delete m_Controls->Plots[idx];
m_Controls->Plots.erase(m_Controls->Plots.begin() + idx);
m_Controls->DataRequests.erase(m_Controls->DataRequests.begin() + idx);
m_Controls->PlotComboBox->removeItem(idx);
if (m_Controls->Plots.size() == 0)
AddPlot();
else
m_Controls->PlotComboBox->setCurrentIndex(idx);
}
void QPlotSetWidget::SwitchPlot()
{
//if (m_Controls->GraphProperty->count() <= 0) return;
//std::string property = m_Controls->GraphProperty->currentText().toStdString();
//if (m_Controls->currPlot != nullptr)
//{
// m_Controls->DataGraphWidget->layout()->removeWidget(&m_Controls->currPlot->GetView());
// m_Controls->currPlot->GetView().hide();
//}
//m_Controls->currPlot = m_Controls->Map[property];
//m_Controls->DataGraphWidget->layout()->addWidget(&m_Controls->currPlot->GetView());
//m_Controls->currPlot->GetView().show();
int idx = m_Controls->PlotComboBox->currentIndex();
if (m_Controls->Plots.size() == 0)
return;
for (QPulsePlot* plot : m_Controls->Plots)
plot->GetView().hide();
m_Controls->Plots[idx]->GetView().show();
}
void QPlotSetWidget::AtSteadyState(PhysiologyEngine& pulse)
{
}
void QPlotSetWidget::AtSteadyStateUpdateUI()
{
Reset();
}
void QPlotSetWidget::ProcessPhysiology(PhysiologyEngine& pulse)
{// This is called from a thread, you should NOT update UI here
// This is where we pull data from pulse, and push any actions to it
double v;
SEDataRequest* dr;
double time = pulse.GetSimulationTime(TimeUnit::s);
// The DataRequestView updated all DataRequests,
// Now just push the values into the plots
for (size_t i = 0; i < m_Controls->Plots.size(); i++)
{
dr = m_Controls->DataRequests[i];
if (dr->HasUnit())
v = pulse.GetEngineTracker()->GetScalar(*dr)->GetValue(*dr->GetUnit());
else
v = pulse.GetEngineTracker()->GetScalar(*dr)->GetValue();
m_Controls->Plots[i]->Append(time, v);
}
}
void QPlotSetWidget::PhysiologyUpdateUI()
{
if (!m_Controls->PlotComboBox->isHidden())
{
int idx = m_Controls->PlotComboBox->currentIndex();
m_Controls->Plots[idx]->UpdateUI();
}
}
\ No newline at end of file
/* Distributed under the Apache License, Version 2.0.
See accompanying NOTICE file for details.*/
#pragma once
#include <QDialog>
#include "QPulse.h"
#include "QPulsePlot.h"
namespace Ui {
class PlotSetWidget;
}
class QPlotSetWidget : public QDialog//, public PulseListener
{
Q_OBJECT
public:
explicit QPlotSetWidget(QPulse& qp, QWidget *parent = nullptr);
virtual ~QPlotSetWidget();
signals:
protected slots:
void SwitchPlot();
void AddPlot();
void RemovePlot();
private:
class Controls;
Controls* m_Controls;
};
#pragma once
#include <QDockWidget>
#include "QPulse.h"
#include "QPulsePlot.h"
namespace Ui {
class PlotSetWidget;
}
class QPlotSetWidget : public QDockWidget, public PulseListener
{
Q_OBJECT
public:
explicit QPlotSetWidget(QPulse& qp, QWidget *parent = Q_NULLPTR, Qt::WindowFlags flags = Qt::WindowFlags());
virtual ~QPlotSetWidget();
void Reset();
void AtSteadyState(PhysiologyEngine& pulse);
void AtSteadyStateUpdateUI();// Main Window will call this to update UI Components
void ProcessPhysiology(PhysiologyEngine& pulse);
void PhysiologyUpdateUI();// Main Window will call this to update UI Components
signals:
protected slots:
void SwitchPlot();
void AddPlot();
void RemovePlot();
void AddDataRequest();
void CancelDataRequest();
private:
class Controls;
Controls* m_Controls;
};
......@@ -115,7 +115,7 @@ void QPulsePlot::UpdateUI(bool pad)
m_Data->Chart->axisY()->setRange(m_Data->MinY, m_Data->MaxY);
m_Data->Chart->axisX()->setRange(m_Data->Times[0], m_Data->Times[size - 1]);
m_Data->Series->replace(points);
//m_Data->View->setVisible(true);
m_Data->View->setVisible(true);
}
m_Data->Mutex.unlock();
}
......
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>DataRequestWidget</class>
<widget class="QWidget" name="DataRequestWidget">
<widget class="QDockWidget" name="DataRequestWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>404</width>
<height>528</height>
<width>413</width>
<height>467</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
<horstretch>2</horstretch>
<verstretch>2</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>300</width>
<height>400</height>
<width>326</width>
<height>110</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>450</width>
<height>600</height>
<width>524287</width>
<height>524287</height>
</size>
</property>
<property name="baseSize">
<size>
<width>300</width>
<height>400</height>
</size>
</property>
<property name="windowTitle">
<string>Form</string>
<property name="autoFillBackground">
<bool>true</bool>
</property>
<property name="styleSheet">
<string notr="true">background: white</string>
<string notr="true"/>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QVBoxLayout" name="DataRequestLayout">
<item>
<widget class="QWidget" name="SelectionsWidget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QVBoxLayout" name="SelectionsLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="windowTitle">
<string>DockWidget</string>
</property>
<widget class="QWidget" name="DataRequest">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QWidget" name="SelectionsWidget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="LeftSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>41</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QWidget" name="Selections" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QComboBox" name="CategoryBox">
<property name="minimumSize">
......@@ -65,60 +90,32 @@
<height>5</height>
</size>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="DataRequestButtons" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>