Merge branch 'plasma'

monitor
Roeland Jansen 2022-08-19 07:34:38 +02:00
commit bd097dc3a5
3 zmienionych plików z 519 dodań i 51 usunięć

Wyświetl plik

@ -617,20 +617,21 @@ void wfmain::receiveStatusUpdate(networkStatus status)
void wfmain::setupPlots()
{
// Line 290--
spectrumDrawLock = true;
plot = ui->plot; // rename it waterfall.
plot = ui->plot;
wf = ui->waterfall;
freqIndicatorLine = new QCPItemLine(plot);
freqIndicatorLine->setAntialiased(true);
freqIndicatorLine->setPen(QPen(Qt::blue));
//
ui->plot->addGraph(); // primary
ui->plot->addGraph(0, 0); // secondary, peaks, same axis as first?
ui->plot->addGraph(0, 0); // secondary, peaks, same axis as first.
ui->plot->addLayer( "Top Layer", ui->plot->layer("main"));
ui->plot->graph(0)->setLayer("Top Layer");
ui->waterfall->addGraph();
colorMap = new QCPColorMap(wf->xAxis, wf->yAxis);
@ -1049,6 +1050,28 @@ void wfmain::setUIToPrefs()
on_drawPeakChk_clicked(prefs.drawPeaks);
drawPeaks = prefs.drawPeaks;
underlayMode = prefs.underlayMode;
switch(underlayMode)
{
case underlayNone:
ui->underlayNone->setChecked(true);
break;
case underlayPeakHold:
ui->underlayPeakHold->setChecked(true);
break;
case underlayPeakBuffer:
ui->underlayPeakBuffer->setChecked(true);
break;
case underlayAverageBuffer:
ui->underlayAverageBuffer->setChecked(true);
break;
default:
break;
}
ui->underlayBufferSlider->setValue(prefs.underlayBufferSize);
on_underlayBufferSlider_valueChanged(prefs.underlayBufferSize);
ui->wfAntiAliasChk->setChecked(prefs.wfAntiAlias);
on_wfAntiAliasChk_clicked(prefs.wfAntiAlias);
@ -1058,6 +1081,12 @@ void wfmain::setUIToPrefs()
ui->wfLengthSlider->setValue(prefs.wflength);
prepareWf(prefs.wflength);
ui->topLevelSlider->setValue(prefs.plotCeiling);
ui->botLevelSlider->setValue(prefs.plotFloor);
plot->yAxis->setRange(QCPRange(prefs.plotFloor, prefs.plotCeiling));
colorMap->setDataRange(QCPRange(prefs.plotFloor, prefs.plotCeiling));
ui->wfthemeCombo->setCurrentIndex(ui->wfthemeCombo->findData(prefs.wftheme));
colorMap->setGradient(static_cast<QCPColorGradient::GradientPreset>(prefs.wftheme));
@ -1249,6 +1278,8 @@ void wfmain::setDefPrefs()
defPrefs.useDarkMode = true;
defPrefs.useSystemTheme = false;
defPrefs.drawPeaks = true;
defPrefs.underlayMode = underlayNone;
defPrefs.underlayBufferSize = 64;
defPrefs.wfAntiAlias = false;
defPrefs.wfInterpolate = true;
defPrefs.stylesheetPath = QString("qdarkstyle/style.qss");
@ -1265,6 +1296,8 @@ void wfmain::setDefPrefs()
defPrefs.localAFgain = 255;
defPrefs.wflength = 160;
defPrefs.wftheme = static_cast<int>(QCPColorGradient::gpJet);
defPrefs.plotFloor = 0;
defPrefs.plotCeiling = 160;
defPrefs.confirmExit = true;
defPrefs.confirmPowerOff = true;
defPrefs.meter2Type = meterNone;
@ -1292,7 +1325,15 @@ void wfmain::loadSettings()
prefs.useDarkMode = settings->value("UseDarkMode", defPrefs.useDarkMode).toBool();
prefs.useSystemTheme = settings->value("UseSystemTheme", defPrefs.useSystemTheme).toBool();
prefs.wftheme = settings->value("WFTheme", defPrefs.wftheme).toInt();
prefs.plotFloor = settings->value("plotFloor", defPrefs.plotFloor).toInt();
prefs.plotCeiling = settings->value("plotCeiling", defPrefs.plotCeiling).toInt();
plotFloor = prefs.plotFloor;
plotCeiling = prefs.plotCeiling;
wfFloor = prefs.plotFloor;
wfCeiling = prefs.plotCeiling;
prefs.drawPeaks = settings->value("DrawPeaks", defPrefs.drawPeaks).toBool();
prefs.underlayBufferSize = settings->value("underlayBufferSize", defPrefs.underlayBufferSize).toInt();
prefs.underlayMode = static_cast<underlay_t>(settings->value("underlayMode", defPrefs.underlayMode).toInt());
prefs.wfAntiAlias = settings->value("WFAntiAlias", defPrefs.wfAntiAlias).toBool();
prefs.wfInterpolate = settings->value("WFInterpolate", defPrefs.wfInterpolate).toBool();
prefs.wflength = (unsigned int)settings->value("WFLength", defPrefs.wflength).toInt();
@ -1800,9 +1841,13 @@ void wfmain::saveSettings()
settings->setValue("UseSystemTheme", prefs.useSystemTheme);
settings->setValue("UseDarkMode", prefs.useDarkMode);
settings->setValue("DrawPeaks", prefs.drawPeaks);
settings->setValue("underlayMode", prefs.underlayMode);
settings->setValue("underlayBufferSize", prefs.underlayBufferSize);
settings->setValue("WFAntiAlias", prefs.wfAntiAlias);
settings->setValue("WFInterpolate", prefs.wfInterpolate);
settings->setValue("WFTheme", prefs.wftheme);
settings->setValue("plotFloor", prefs.plotFloor);
settings->setValue("plotCeiling", prefs.plotCeiling);
settings->setValue("StylesheetPath", prefs.stylesheetPath);
settings->setValue("splitter", ui->splitter->saveState());
settings->setValue("windowGeometry", saveGeometry());
@ -2035,6 +2080,15 @@ void wfmain::prepareWf(unsigned int wfLength)
QByteArray empty((int)spectWidth, '\x01');
spectrumPeaks = QByteArray( (int)spectWidth, '\x01' );
if(spectrumPlasmaSize == 0)
spectrumPlasmaSize = 128;
//spectrumPlasma.resize(spectrumPlasmaSize);
for(unsigned int p=0; p < spectrumPlasmaSize; p++)
{
spectrumPlasma.append(empty);
}
//wfimage.resize(wfLengthMax);
if((unsigned int)wfimage.size() < wfLengthMax)
@ -3182,6 +3236,10 @@ void wfmain::receiveRigID(rigCapabilities rigCaps)
}
setWindowTitle(rigCaps.modelName);
this->spectWidth = rigCaps.spectLenMax; // used once haveRigCaps is true.
//wfCeiling = rigCaps.spectAmpMax;
//plotCeiling = rigCaps.spectAmpMax;
ui->topLevelSlider->setMaximum(rigCaps.spectAmpMax);
haveRigCaps = true;
// Added so that server receives rig capabilities.
emit sendRigCaps(rigCaps);
@ -3301,6 +3359,8 @@ void wfmain::receiveRigID(rigCapabilities rigCaps)
{
ui->scopeBWCombo->addItem(rigCaps.scopeCenterSpans.at(i).name, (int)rigCaps.scopeCenterSpans.at(i).cstype);
}
plot->yAxis->setRange(QCPRange(prefs.plotFloor, prefs.plotCeiling));
colorMap->setDataRange(QCPRange(prefs.plotFloor, prefs.plotCeiling));
} else {
ui->scopeBWCombo->setHidden(true);
}
@ -3473,15 +3533,19 @@ void wfmain::receiveSpectrumData(QByteArray spectrum, double startFreq, double e
return;
}
QElapsedTimer performanceTimer;
bool updateRange = false;
if((startFreq != oldLowerFreq) || (endFreq != oldUpperFreq))
{
// If the frequency changed and we were drawing peaks, now is the time to clearn them
if(drawPeaks)
if(underlayMode == underlayPeakHold)
{
// TODO: create non-button function to do this
// This will break if the button is ever moved or renamed.
on_clearPeakBtn_clicked();
}
// TODO: Add clear-out for the buffer
}
oldLowerFreq = startFreq;
@ -3512,7 +3576,7 @@ void wfmain::receiveSpectrumData(QByteArray spectrum, double startFreq, double e
{
//x[i] = (i * (endFreq-startFreq)/specLen) + startFreq;
y[i] = (unsigned char)spectrum.at(i);
if(drawPeaks)
if(underlayMode == underlayPeakHold)
{
if((unsigned char)spectrum.at(i) > (unsigned char)spectrumPeaks.at(i))
{
@ -3520,46 +3584,101 @@ void wfmain::receiveSpectrumData(QByteArray spectrum, double startFreq, double e
}
y2[i] = (unsigned char)spectrumPeaks.at(i);
}
}
plasmaMutex.lock();
spectrumPlasma.push_front(spectrum);
spectrumPlasma.pop_back();
//spectrumPlasma.resize(spectrumPlasmaSize);
plasmaMutex.unlock();
// HACK DO NOT CHECK IN:
drawPeaks = false;
drawPlasma = true;
if(!spectrumDrawLock)
{
if((plotFloor != oldPlotFloor) || (plotCeiling != oldPlotCeiling))
updateRange = true;
//ui->qcp->addGraph();
plot->graph(0)->setData(x,y);
plot->graph(0)->setData(x,y, true);
if((freq.MHzDouble < endFreq) && (freq.MHzDouble > startFreq))
{
freqIndicatorLine->start->setCoords(freq.MHzDouble,0);
freqIndicatorLine->end->setCoords(freq.MHzDouble,160);
freqIndicatorLine->end->setCoords(freq.MHzDouble,rigCaps.spectAmpMax);
}
if(drawPeaks)
if(underlayMode == underlayPeakHold)
{
plot->graph(1)->setData(x,y2); // peaks
plot->graph(1)->setData(x,y2, true); // peaks
} else if (underlayMode != underlayNone) {
computePlasma();
plot->graph(1)->setData(x,spectrumPlasmaLine);
} else {
plot->graph(1)->setData(x,y2, true); // peaks, but probably cleared out
}
plot->yAxis->setRange(0, rigCaps.spectAmpMax+1);
if(updateRange)
plot->yAxis->setRange(prefs.plotFloor, prefs.plotCeiling);
plot->xAxis->setRange(startFreq, endFreq);
plot->replot();
if(specLen == spectWidth)
{
wfimage.prepend(spectrum);
wfimage.resize(wfLengthMax);
wfimage.squeeze();
wfimage.pop_back();
QByteArray wfRow;
// Waterfall:
for(int row = 0; row < wfLength; row++)
{
wfRow = wfimage.at(row);
for(int col = 0; col < spectWidth; col++)
{
colorMap->data()->setCell( col, row, wfimage.at(row).at(col));
colorMap->data()->setCell( col, row, wfRow.at(col));
}
}
if(updateRange)
{
colorMap->setDataRange(QCPRange(wfFloor, wfCeiling));
}
wf->yAxis->setRange(0,wfLength - 1);
wf->xAxis->setRange(0, spectWidth-1);
wf->replot();
}
oldPlotFloor = plotFloor;
oldPlotCeiling = plotCeiling;
}
}
wf->yAxis->setRange(0,wfLength - 1);
wf->xAxis->setRange(0, spectWidth-1);
wf->replot();
void wfmain::computePlasma()
{
plasmaMutex.lock();
spectrumPlasmaLine.clear();
spectrumPlasmaLine.resize(spectWidth);
int specPlasmaSize = spectrumPlasma.size();
if(underlayMode == underlayAverageBuffer)
{
for(int col=0; col < spectWidth; col++)
{
for(int pos=0; pos < specPlasmaSize; pos++)
{
spectrumPlasmaLine[col] += spectrumPlasma[pos][col];
}
spectrumPlasmaLine[col] = spectrumPlasmaLine[col] / specPlasmaSize;
}
} else if (underlayMode == underlayPeakBuffer){
// peak mode, running peak display
for(int col=0; col < spectWidth; col++)
{
for(int pos=0; pos < specPlasmaSize; pos++)
{
if((double)(spectrumPlasma[pos][col]) > spectrumPlasmaLine[col])
spectrumPlasmaLine[col] = spectrumPlasma[pos][col];
}
}
}
plasmaMutex.unlock();
}
void wfmain::receiveSpectrumMode(spectrumMode spectMode)
@ -5744,32 +5863,6 @@ void wfmain::on_radioStatusBtn_clicked()
}
}
// --- DEBUG FUNCTION ---
void wfmain::on_debugBtn_clicked()
{
qInfo(logSystem()) << "Debug button pressed.";
// issueDelayedCommand(cmdGetRigID);
//emit getRigCIV();
//trxadj->show();
//setRadioTimeDatePrep();
//wf->setInteraction(QCP::iRangeZoom, true);
//wf->setInteraction(QCP::iRangeDrag, true);
bool ok;
int height = QInputDialog::getInt(this, "wfview Radio Polling Setup", "Poll Timing Interval (ms)", 350, 1, 500, 1, &ok );
this->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
this->setMaximumSize(QSize(1025,height));
this->setMinimumSize(QSize(1025,height));
//this->setMaximumSize(QSize(929, 270));
//this->setMinimumSize(QSize(929, 270));
resize(minimumSize());
adjustSize(); // main window
adjustSize();
}
void wfmain::setAudioDevicesUI()
{
@ -6000,4 +6093,125 @@ void wfmain::on_audioSystemCombo_currentIndexChanged(int value)
{
prefs.audioSystem = static_cast<audioType>(value);
setAudioDevicesUI(); // Force all audio devices to update
}
}
void wfmain::on_topLevelSlider_valueChanged(int value)
{
wfCeiling = value;
plotCeiling = value;
prefs.plotCeiling = value;
plot->yAxis->setRange(QCPRange(plotFloor, plotCeiling));
colorMap->setDataRange(QCPRange(wfFloor, wfCeiling));
}
void wfmain::on_botLevelSlider_valueChanged(int value)
{
wfFloor = value;
plotFloor = value;
prefs.plotFloor = value;
plot->yAxis->setRange(QCPRange(plotFloor, plotCeiling));
colorMap->setDataRange(QCPRange(wfFloor, wfCeiling));
}
void wfmain::on_underlayBufferSlider_valueChanged(int value)
{
resizePlasmaBuffer(value);
prefs.underlayBufferSize = value;
}
void wfmain::resizePlasmaBuffer(int newSize)
{
QByteArray empty((int)spectWidth, '\x01');
plasmaMutex.lock();
int oldSize = spectrumPlasma.size();
if(oldSize < newSize)
{
spectrumPlasma.resize(newSize);
for(int p=oldSize; p < newSize; p++)
{
spectrumPlasma.append(empty);
}
} else if (oldSize > newSize){
for(int p = oldSize; p > newSize; p--)
{
spectrumPlasma.pop_back();
}
}
spectrumPlasma.squeeze();
plasmaMutex.unlock();
}
void wfmain::on_underlayNone_toggled(bool checked)
{
ui->underlayBufferSlider->setDisabled(checked);
if(checked)
{
underlayMode = underlayNone;
prefs.underlayMode = underlayMode;
on_clearPeakBtn_clicked();
}
}
void wfmain::on_underlayPeakHold_toggled(bool checked)
{
ui->underlayBufferSlider->setDisabled(checked);
if(checked)
{
underlayMode = underlayPeakHold;
prefs.underlayMode = underlayMode;
on_clearPeakBtn_clicked();
}
}
void wfmain::on_underlayPeakBuffer_toggled(bool checked)
{
ui->underlayBufferSlider->setDisabled(!checked);
if(checked)
{
underlayMode = underlayPeakBuffer;
prefs.underlayMode = underlayMode;
}
}
void wfmain::on_underlayAverageBuffer_toggled(bool checked)
{
ui->underlayBufferSlider->setDisabled(!checked);
if(checked)
{
underlayMode = underlayAverageBuffer;
prefs.underlayMode = underlayMode;
}
}
// --- DEBUG FUNCTION ---
void wfmain::on_debugBtn_clicked()
{
qInfo(logSystem()) << "Debug button pressed.";
// issueDelayedCommand(cmdGetRigID);
//emit getRigCIV();
//trxadj->show();
//setRadioTimeDatePrep();
//wf->setInteraction(QCP::iRangeZoom, true);
//wf->setInteraction(QCP::iRangeDrag, true);
plot->yAxis->setRange(QCPRange(plotFloor, plotCeiling));
colorMap->setDataRange(QCPRange(wfFloor, wfCeiling));
// bool ok;
// int height = QInputDialog::getInt(this, "wfview window fixed height", "number: ", 350, 1, 500, 1, &ok );
// this->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
// this->setMaximumSize(QSize(1025,height));
// this->setMinimumSize(QSize(1025,height));
// //this->setMaximumSize(QSize(929, 270));
// //this->setMinimumSize(QSize(929, 270));
// resize(minimumSize());
// adjustSize(); // main window
// adjustSize();
}

Wyświetl plik

@ -14,6 +14,8 @@
#include <QSettings>
#include <QShortcut>
#include <QMetaType>
#include <QMutex>
#include <QMutexLocker>
#include "logcategories.h"
#include "commhandler.h"
@ -539,6 +541,20 @@ private slots:
void on_audioSystemCombo_currentIndexChanged(int value);
void on_topLevelSlider_valueChanged(int value);
void on_botLevelSlider_valueChanged(int value);
void on_underlayBufferSlider_valueChanged(int value);
void on_underlayNone_toggled(bool checked);
void on_underlayPeakHold_toggled(bool checked);
void on_underlayPeakBuffer_toggled(bool checked);
void on_underlayAverageBuffer_toggled(bool checked);
private:
Ui::wfmain *ui;
void closeEvent(QCloseEvent *event);
@ -557,6 +573,7 @@ private:
void setPlotTheme(QCustomPlot *plot, bool isDark);
void prepareWf();
void prepareWf(unsigned int wfLength);
void computePlasma();
void showHideSpectrum(bool show);
void getInitialRigState();
void setBandButtons();
@ -647,7 +664,24 @@ private:
quint16 wfLength;
bool spectrumDrawLock;
enum underlay_t { underlayNone, underlayPeakHold, underlayPeakBuffer, underlayAverageBuffer };
QByteArray spectrumPeaks;
QVector <double> spectrumPlasmaLine;
QVector <QByteArray> spectrumPlasma;
unsigned int spectrumPlasmaSize = 64;
underlay_t underlayMode = underlayNone;
bool drawPlasma = true;
QMutex plasmaMutex;
void resizePlasmaBuffer(int newSize);
double plotFloor = 0;
double plotCeiling = 160;
double wfFloor = 0;
double wfCeiling = 160;
double oldPlotFloor = -1;
double oldPlotCeiling = 999;
QVector <QByteArray> wfimage;
unsigned int wfLengthMax;
@ -756,6 +790,8 @@ private:
bool useDarkMode;
bool useSystemTheme;
bool drawPeaks;
underlay_t underlayMode = underlayNone;
int underlayBufferSize = 64;
bool wfAntiAlias;
bool wfInterpolate;
QString stylesheetPath;
@ -774,13 +810,14 @@ private:
unsigned char localAFgain;
unsigned int wflength;
int wftheme;
int plotFloor;
int plotCeiling;
bool confirmExit;
bool confirmPowerOff;
meterKind meter2Type;
quint16 tcpPort;
quint8 waterfallFormat;
audioType audioSystem;
// plot scheme
} prefs;
preferences defPrefs;

223
wfmain.ui
Wyświetl plik

@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>940</width>
<width>1002</width>
<height>569</height>
</rect>
</property>
@ -846,6 +846,114 @@
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="topSliderLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<item>
<widget class="QSlider" name="topLevelSlider">
<property name="minimumSize">
<size>
<width>0</width>
<height>70</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>80</height>
</size>
</property>
<property name="toolTip">
<string>Sets the ceiling for the waterfall and spectrum displays</string>
</property>
<property name="accessibleName">
<string>Ceiling for waterfall and spectrum display</string>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>160</number>
</property>
<property name="value">
<number>160</number>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelTop">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>15</height>
</size>
</property>
<property name="text">
<string>Top</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="botAdjustVertLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QSlider" name="botLevelSlider">
<property name="minimumSize">
<size>
<width>0</width>
<height>70</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>80</height>
</size>
</property>
<property name="maximum">
<number>160</number>
</property>
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="labelBot">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>15</height>
</size>
</property>
<property name="text">
<string>Bot</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_16">
<property name="leftMargin">
@ -2066,7 +2174,7 @@
<item>
<widget class="QStackedWidget" name="settingsStack">
<property name="currentIndex">
<number>0</number>
<number>1</number>
</property>
<widget class="QWidget" name="radioAccess">
<layout class="QVBoxLayout" name="verticalLayout_21">
@ -2799,6 +2907,114 @@
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_43">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="underlayLabel">
<property name="text">
<string>Underlay Mode</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="underlayNone">
<property name="text">
<string>None</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
<attribute name="buttonGroup">
<string notr="true">underlayButtonGroup</string>
</attribute>
</widget>
</item>
<item>
<widget class="QRadioButton" name="underlayPeakHold">
<property name="text">
<string>Peak Hold</string>
</property>
<attribute name="buttonGroup">
<string notr="true">underlayButtonGroup</string>
</attribute>
</widget>
</item>
<item>
<widget class="QRadioButton" name="underlayPeakBuffer">
<property name="text">
<string>Peak</string>
</property>
<attribute name="buttonGroup">
<string notr="true">underlayButtonGroup</string>
</attribute>
</widget>
</item>
<item>
<widget class="QRadioButton" name="underlayAverageBuffer">
<property name="text">
<string>Average</string>
</property>
<attribute name="buttonGroup">
<string notr="true">underlayButtonGroup</string>
</attribute>
</widget>
</item>
<item>
<widget class="QLabel" name="label_42">
<property name="text">
<string>Uneerlay Buffer Size:</string>
</property>
</widget>
</item>
<item>
<widget class="QSlider" name="underlayBufferSlider">
<property name="maximumSize">
<size>
<width>100</width>
<height>16777215</height>
</size>
</property>
<property name="minimum">
<number>8</number>
</property>
<property name="maximum">
<number>128</number>
</property>
<property name="value">
<number>64</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_27">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_28">
<item>
@ -3790,7 +4006,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>940</width>
<width>1002</width>
<height>21</height>
</rect>
</property>
@ -3813,5 +4029,6 @@
<connections/>
<buttongroups>
<buttongroup name="buttonGroup"/>
<buttongroup name="underlayButtonGroup"/>
</buttongroups>
</ui>