mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-11-17 13:51:47 -05:00
Enhanced spectrum display: Histogram: define NO_AVX, wider decay range, make stroke and late holdoff adjustable. Added option to show live spectrum (had only max hold before)
This commit is contained in:
parent
528b11ebd1
commit
69101c0629
10
Readme.md
10
Readme.md
@ -107,16 +107,22 @@ Done since the fork
|
||||
- As a consequence of the above added more interesting values for the available sampling rates of the BladeRF plugin
|
||||
- Variable span for the SSB demod down to 1.5 kHz
|
||||
- Filter out CTCSS tones for audio and full CTCSS support in NFMDemod
|
||||
- Enhancement of the NFM squelch
|
||||
- Enhancement of the NFM squelch mimicking professional analog squelch circuits (based on balance between two AF filters)
|
||||
- Added a channel analyzer plugin focusing on measurement (DSA/DSO functionnality). Basic functions.
|
||||
- Added a scope widget in the channel analyzer plugin
|
||||
- Channel analyzer bandwidth up to half the available RF (IF) bandwidth (was 48k fixed)
|
||||
- Enhanced scope display and controls: scale display, better X (time) and Y scales control, grid fit to scale, effectively implementing triggers, trigger on magnitude and phase, properly handling time shift, ...
|
||||
- Enhanced spectrum display: Histogram: define NO_AVX, wider decay range, make stroke and late holdoff adjustable. Added option to show live spectrum (had only max hold before).
|
||||
- Enhanced channel analyzer: enhanced scope and spectrum displays as mentioned above, make the spectrum display synchronous to scope (hence triggerable a la E4406A).
|
||||
|
||||
=====
|
||||
To Do
|
||||
=====
|
||||
|
||||
- Enhance presets management (Edit, Move, Import/Export from/to human readable format like JSON)
|
||||
- Variable scope memory depth
|
||||
- Level calibration
|
||||
- Enhance WFM (stereo, RDS?)
|
||||
- Even more demods ...
|
||||
- Triggering capability like on expensive spectrum analyzers to trap burst signals
|
||||
- recording capability
|
||||
- Tx channels for Rx/Tx boards like BladeRF
|
||||
|
@ -38,10 +38,13 @@ public:
|
||||
void setReferenceLevel(Real referenceLevel);
|
||||
void setPowerRange(Real powerRange);
|
||||
void setDecay(int decay);
|
||||
void setHistoLateHoldoff(int lateHoldoff);
|
||||
void setHistoStroke(int stroke);
|
||||
void setDisplayWaterfall(bool display);
|
||||
void setSsbSpectrum(bool ssbSpectrum);
|
||||
void setInvertedWaterfall(bool inv);
|
||||
void setDisplayMaxHold(bool display);
|
||||
void setDisplayCurrent(bool display);
|
||||
void setDisplayHistogram(bool display);
|
||||
void setDisplayGrid(bool display);
|
||||
void setDisplayGridIntensity(int intensity);
|
||||
@ -96,6 +99,8 @@ private:
|
||||
|
||||
std::vector<Real> m_maxHold;
|
||||
bool m_displayMaxHold;
|
||||
std::vector<Real> m_current;
|
||||
bool m_displayCurrent;
|
||||
|
||||
Real m_waterfallShare;
|
||||
|
||||
|
@ -45,6 +45,7 @@ private:
|
||||
bool m_displayWaterfall;
|
||||
bool m_invertedWaterfall;
|
||||
bool m_displayMaxHold;
|
||||
bool m_displayCurrent;
|
||||
bool m_displayHistogram;
|
||||
bool m_displayGrid;
|
||||
bool m_invert;
|
||||
@ -64,6 +65,7 @@ private slots:
|
||||
void on_waterfall_toggled(bool checked);
|
||||
void on_histogram_toggled(bool checked);
|
||||
void on_maxHold_toggled(bool checked);
|
||||
void on_current_toggled(bool checked);
|
||||
void on_invert_toggled(bool checked);
|
||||
void on_grid_toggled(bool checked);
|
||||
};
|
||||
|
@ -36,6 +36,7 @@ GLSpectrum::GLSpectrum(QWidget* parent) :
|
||||
m_displayGridIntensity(5),
|
||||
m_invertedWaterfall(false),
|
||||
m_displayMaxHold(false),
|
||||
m_displayCurrent(false),
|
||||
m_leftMarginTextureAllocated(false),
|
||||
m_frequencyTextureAllocated(false),
|
||||
m_waterfallBuffer(NULL),
|
||||
@ -86,6 +87,9 @@ GLSpectrum::GLSpectrum(QWidget* parent) :
|
||||
((quint8*)&m_histogramPalette[i])[2] = c.blue();
|
||||
((quint8*)&m_histogramPalette[i])[3] = c.alpha();
|
||||
}
|
||||
|
||||
m_current.resize(m_fftSize);
|
||||
|
||||
m_histogramHoldoffBase = 1; // was 4
|
||||
m_histogramHoldoffCount = m_histogramHoldoffBase;
|
||||
m_histogramLateHoldoff = 1; // was 20
|
||||
@ -169,12 +173,30 @@ void GLSpectrum::setPowerRange(Real powerRange)
|
||||
void GLSpectrum::setDecay(int decay)
|
||||
{
|
||||
m_decay = decay;
|
||||
if(m_decay < -2)
|
||||
m_decay = -2;
|
||||
if(m_decay < 0)
|
||||
m_decay = 0;
|
||||
else if(m_decay > 10)
|
||||
m_decay = 10;
|
||||
}
|
||||
|
||||
void GLSpectrum::setHistoLateHoldoff(int lateHoldoff)
|
||||
{
|
||||
m_histogramLateHoldoff = lateHoldoff;
|
||||
if(m_histogramLateHoldoff < 0)
|
||||
m_histogramLateHoldoff = 0;
|
||||
else if(m_histogramLateHoldoff > 20)
|
||||
m_histogramLateHoldoff = 20;
|
||||
}
|
||||
|
||||
void GLSpectrum::setHistoStroke(int stroke)
|
||||
{
|
||||
m_histogramStroke = stroke;
|
||||
if(m_histogramStroke < 4)
|
||||
m_histogramStroke = 4;
|
||||
else if(m_histogramStroke > 240)
|
||||
m_histogramStroke = 240;
|
||||
}
|
||||
|
||||
void GLSpectrum::setSampleRate(qint32 sampleRate)
|
||||
{
|
||||
m_sampleRate = sampleRate;
|
||||
@ -212,6 +234,18 @@ void GLSpectrum::setDisplayMaxHold(bool display)
|
||||
update();
|
||||
}
|
||||
|
||||
void GLSpectrum::setDisplayCurrent(bool display)
|
||||
{
|
||||
if(display && (m_current.size() < (uint)m_fftSize)) {
|
||||
m_current.resize(m_fftSize);
|
||||
}
|
||||
|
||||
m_displayCurrent = display;
|
||||
m_changesPending = true;
|
||||
stopDrag();
|
||||
update();
|
||||
}
|
||||
|
||||
void GLSpectrum::setDisplayHistogram(bool display)
|
||||
{
|
||||
m_displayHistogram = display;
|
||||
@ -333,12 +367,23 @@ void GLSpectrum::updateHistogram(const std::vector<Real>& spectrum)
|
||||
m_histogramHoldoffCount = m_histogramHoldoffBase;
|
||||
}
|
||||
|
||||
if(m_current.size() < (uint)m_fftSize)
|
||||
m_current.resize(m_fftSize);
|
||||
|
||||
#define NO_AVX
|
||||
#ifdef NO_AVX
|
||||
for(int i = 0; i < m_fftSize; i++) {
|
||||
int v = (int)((spectrum[i] - m_referenceLevel) * 100.0 / m_powerRange + 100.0);
|
||||
|
||||
if((v >= 0) && (v <= 99)) {
|
||||
if (v < 0) {
|
||||
m_current[i] = m_referenceLevel - m_powerRange;
|
||||
}
|
||||
else if (v > 99) {
|
||||
m_current[i] = m_referenceLevel;
|
||||
}
|
||||
else {
|
||||
//m_current[i] = m_referenceLevel - m_powerRange + (v * m_powerRange) / 99.0;
|
||||
m_current[i] = spectrum[i];
|
||||
b = m_histogram + i * 100 + v;
|
||||
if(*b < 220)
|
||||
*b += m_histogramStroke; // was 4
|
||||
@ -517,7 +562,7 @@ void GLSpectrum::paintGL()
|
||||
}
|
||||
|
||||
// paint histogram
|
||||
if(m_displayHistogram || m_displayMaxHold) {
|
||||
if(m_displayHistogram || m_displayMaxHold || m_displayCurrent) {
|
||||
glPushMatrix();
|
||||
glTranslatef(m_glHistogramRect.x(), m_glHistogramRect.y(), 0);
|
||||
glScalef(m_glHistogramRect.width(), m_glHistogramRect.height(), 1);
|
||||
@ -613,7 +658,7 @@ void GLSpectrum::paintGL()
|
||||
}
|
||||
|
||||
// paint left scales (time and power)
|
||||
if(m_displayWaterfall || m_displayMaxHold || m_displayHistogram ) {
|
||||
if(m_displayWaterfall || m_displayMaxHold || m_displayCurrent || m_displayHistogram ) {
|
||||
glBindTexture(GL_TEXTURE_2D, m_leftMarginTexture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
@ -640,7 +685,7 @@ void GLSpectrum::paintGL()
|
||||
}
|
||||
|
||||
// paint frequency scale
|
||||
if(m_displayWaterfall || m_displayMaxHold || m_displayHistogram ) {
|
||||
if(m_displayWaterfall || m_displayMaxHold || m_displayCurrent || m_displayHistogram ) {
|
||||
glBindTexture(GL_TEXTURE_2D, m_frequencyTexture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
@ -753,6 +798,31 @@ void GLSpectrum::paintGL()
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
// paint current spectrum line on top of histogram
|
||||
if(m_displayCurrent) {
|
||||
glPushMatrix();
|
||||
glTranslatef(m_glHistogramRect.x(), m_glHistogramRect.y(), 0);
|
||||
glScalef(m_glHistogramRect.width() / (float)(m_fftSize - 1), -m_glHistogramRect.height() / m_powerRange, 1);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
glLineWidth(1.0f);
|
||||
glColor3f(1.0f, 1.0f, 0.25f); // intense yellow
|
||||
Real bottom = -m_powerRange;
|
||||
glBegin(GL_LINE_STRIP);
|
||||
for(int i = 0; i < m_fftSize; i++) {
|
||||
Real v = m_current[i] - m_referenceLevel;
|
||||
if(v > 0)
|
||||
v = 0;
|
||||
else if(v < bottom)
|
||||
v = bottom;
|
||||
glVertex2f(i, v);
|
||||
}
|
||||
glEnd();
|
||||
glDisable(GL_LINE_SMOOTH);
|
||||
glPopMatrix();
|
||||
}
|
||||
|
||||
// paint waterfall grid
|
||||
if(m_displayWaterfall && m_displayGrid) {
|
||||
glEnable(GL_BLEND);
|
||||
@ -800,7 +870,7 @@ void GLSpectrum::paintGL()
|
||||
}
|
||||
|
||||
// paint histogram grid
|
||||
if((m_displayHistogram || m_displayMaxHold) && (m_displayGrid)) {
|
||||
if((m_displayHistogram || m_displayMaxHold || m_displayCurrent) && (m_displayGrid)) {
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glLineWidth(1.0f);
|
||||
@ -881,7 +951,7 @@ void GLSpectrum::applyChanges()
|
||||
int leftMargin;
|
||||
int rightMargin = fm.width("000");
|
||||
|
||||
if(m_displayWaterfall && (m_displayHistogram | m_displayMaxHold))
|
||||
if(m_displayWaterfall && (m_displayHistogram | m_displayMaxHold | m_displayCurrent))
|
||||
{
|
||||
waterfallHeight = height() * m_waterfallShare - 1;
|
||||
|
||||
@ -1041,7 +1111,7 @@ void GLSpectrum::applyChanges()
|
||||
(float)1
|
||||
);
|
||||
}
|
||||
else if(m_displayHistogram || m_displayMaxHold)
|
||||
else if(m_displayHistogram || m_displayMaxHold || m_displayCurrent)
|
||||
{
|
||||
bottomMargin = frequencyScaleHeight;
|
||||
frequencyScaleTop = height() - bottomMargin;
|
||||
@ -1133,7 +1203,7 @@ void GLSpectrum::applyChanges()
|
||||
1);
|
||||
*/
|
||||
|
||||
if(m_displayHistogram || m_displayMaxHold || m_displayWaterfall) {
|
||||
if(m_displayHistogram || m_displayMaxHold || m_displayCurrent || m_displayWaterfall) {
|
||||
dv->m_rect.setRect(m_frequencyScale.getPosFromValue(xc) + leftMargin - 1,
|
||||
topMargin,
|
||||
5,
|
||||
@ -1170,7 +1240,7 @@ void GLSpectrum::applyChanges()
|
||||
}
|
||||
}
|
||||
}
|
||||
if(m_displayHistogram || m_displayMaxHold) {
|
||||
if(m_displayHistogram || m_displayMaxHold || m_displayCurrent) {
|
||||
tickList = &m_powerScale.getTickList();
|
||||
for(int i = 0; i < tickList->count(); i++) {
|
||||
tick = &(*tickList)[i];
|
||||
@ -1191,7 +1261,7 @@ void GLSpectrum::applyChanges()
|
||||
m_leftMarginTextureAllocated = true;
|
||||
}
|
||||
// prepare frequency scale
|
||||
if(m_displayWaterfall || m_displayHistogram || m_displayMaxHold){
|
||||
if(m_displayWaterfall || m_displayHistogram || m_displayMaxHold || m_displayCurrent){
|
||||
m_frequencyPixmap = QPixmap(width(), frequencyScaleHeight);
|
||||
m_frequencyPixmap.fill(Qt::transparent);
|
||||
{
|
||||
@ -1320,7 +1390,7 @@ void GLSpectrum::applyChanges()
|
||||
|
||||
void GLSpectrum::mouseMoveEvent(QMouseEvent* event)
|
||||
{
|
||||
if(m_displayWaterfall && (m_displayWaterfall || m_displayHistogram || m_displayMaxHold)) {
|
||||
if(m_displayWaterfall && (m_displayWaterfall || m_displayHistogram || m_displayMaxHold || m_displayCurrent)) {
|
||||
if(m_frequencyScaleRect.contains(event->pos())) {
|
||||
if(m_cursorState == CSNormal) {
|
||||
setCursor(Qt::SizeVerCursor);
|
||||
@ -1355,7 +1425,7 @@ void GLSpectrum::mouseMoveEvent(QMouseEvent* event)
|
||||
m_channelMarkerStates[m_cursorChannel]->m_channelMarker->setCenterFrequency(freq);
|
||||
}
|
||||
|
||||
if(m_displayWaterfall || m_displayHistogram || m_displayMaxHold) {
|
||||
if(m_displayWaterfall || m_displayHistogram || m_displayMaxHold || m_displayCurrent) {
|
||||
for(int i = 0; i < m_channelMarkerStates.size(); ++i) {
|
||||
if(m_channelMarkerStates[i]->m_rect.contains(event->pos())) {
|
||||
if(m_cursorState == CSNormal) {
|
||||
|
@ -23,6 +23,7 @@ GLSpectrumGUI::GLSpectrumGUI(QWidget* parent) :
|
||||
m_displayWaterfall(true),
|
||||
m_invertedWaterfall(false),
|
||||
m_displayMaxHold(false),
|
||||
m_displayCurrent(false),
|
||||
m_displayHistogram(false),
|
||||
m_displayGrid(false),
|
||||
m_invert(true)
|
||||
@ -85,6 +86,7 @@ QByteArray GLSpectrumGUI::serialize() const
|
||||
s.writeS32(13, m_displayGridIntensity);
|
||||
s.writeS32(14, m_histogramLateHoldoff);
|
||||
s.writeS32(15, m_histogramStroke);
|
||||
s.writeBool(16, m_displayCurrent);
|
||||
return s.final();
|
||||
}
|
||||
|
||||
@ -113,6 +115,7 @@ bool GLSpectrumGUI::deserialize(const QByteArray& data)
|
||||
d.readS32(13, &m_displayGridIntensity, 0);
|
||||
d.readS32(14, &m_histogramLateHoldoff, 1);
|
||||
d.readS32(15, &m_histogramStroke, 40);
|
||||
d.readBool(16, &m_displayCurrent, false);
|
||||
applySettings();
|
||||
return true;
|
||||
} else {
|
||||
@ -137,6 +140,7 @@ void GLSpectrumGUI::applySettings()
|
||||
ui->stroke->setSliderPosition(m_histogramStroke);
|
||||
ui->waterfall->setChecked(m_displayWaterfall);
|
||||
ui->maxHold->setChecked(m_displayMaxHold);
|
||||
ui->current->setChecked(m_displayCurrent);
|
||||
ui->histogram->setChecked(m_displayHistogram);
|
||||
ui->invert->setChecked(m_invert);
|
||||
ui->grid->setChecked(m_displayGrid);
|
||||
@ -150,8 +154,11 @@ void GLSpectrumGUI::applySettings()
|
||||
m_glSpectrum->setDisplayWaterfall(m_displayWaterfall);
|
||||
m_glSpectrum->setInvertedWaterfall(m_invertedWaterfall);
|
||||
m_glSpectrum->setDisplayMaxHold(m_displayMaxHold);
|
||||
m_glSpectrum->setDisplayCurrent(m_displayCurrent);
|
||||
m_glSpectrum->setDisplayHistogram(m_displayHistogram);
|
||||
m_glSpectrum->setDecay(m_decay);
|
||||
m_glSpectrum->setHistoLateHoldoff(m_histogramLateHoldoff);
|
||||
m_glSpectrum->setHistoStroke(m_histogramStroke);
|
||||
m_glSpectrum->setInvertedWaterfall(m_invert);
|
||||
m_glSpectrum->setDisplayGrid(m_displayGrid);
|
||||
m_glSpectrum->setDisplayGridIntensity(m_displayGridIntensity);
|
||||
@ -198,13 +205,14 @@ void GLSpectrumGUI::on_decay_valueChanged(int index)
|
||||
|
||||
void GLSpectrumGUI::on_holdoff_valueChanged(int index)
|
||||
{
|
||||
if (index < 1) {
|
||||
if (index < 0) {
|
||||
return;
|
||||
}
|
||||
m_histogramLateHoldoff = index;
|
||||
ui->holdoff->setToolTip(QString("Holdoff: %1").arg(m_histogramLateHoldoff));
|
||||
if(m_glSpectrum != NULL)
|
||||
m_glSpectrum->setDecay(m_decay);
|
||||
//ui->holdoff->setToolTip(QString("Holdoff: %1").arg(m_histogramLateHoldoff));
|
||||
if(m_glSpectrum != NULL) {
|
||||
applySettings();
|
||||
}
|
||||
}
|
||||
|
||||
void GLSpectrumGUI::on_stroke_valueChanged(int index)
|
||||
@ -213,9 +221,10 @@ void GLSpectrumGUI::on_stroke_valueChanged(int index)
|
||||
return;
|
||||
}
|
||||
m_histogramStroke = index;
|
||||
ui->stroke->setToolTip(QString("Stroke: %1").arg(m_histogramStroke));
|
||||
if(m_glSpectrum != NULL)
|
||||
m_glSpectrum->setDecay(m_decay);
|
||||
//ui->stroke->setToolTip(QString("Stroke: %1").arg(m_histogramStroke));
|
||||
if(m_glSpectrum != NULL) {
|
||||
applySettings();
|
||||
}
|
||||
}
|
||||
|
||||
void GLSpectrumGUI::on_waterfall_toggled(bool checked)
|
||||
@ -239,6 +248,13 @@ void GLSpectrumGUI::on_maxHold_toggled(bool checked)
|
||||
m_glSpectrum->setDisplayMaxHold(m_displayMaxHold);
|
||||
}
|
||||
|
||||
void GLSpectrumGUI::on_current_toggled(bool checked)
|
||||
{
|
||||
m_displayCurrent = checked;
|
||||
if(m_glSpectrum != NULL)
|
||||
m_glSpectrum->setDisplayCurrent(m_displayCurrent);
|
||||
}
|
||||
|
||||
void GLSpectrumGUI::on_invert_toggled(bool checked)
|
||||
{
|
||||
m_invert = checked;
|
||||
|
@ -6,7 +6,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>234</width>
|
||||
<width>273</width>
|
||||
<height>94</height>
|
||||
</rect>
|
||||
</property>
|
||||
@ -234,7 +234,7 @@
|
||||
<string>Decay:</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>10</number>
|
||||
<number>240</number>
|
||||
</property>
|
||||
<property name="pageStep">
|
||||
<number>1</number>
|
||||
@ -253,10 +253,10 @@
|
||||
<string>Holdoff:</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
<number>20</number>
|
||||
</property>
|
||||
<property name="pageStep">
|
||||
<number>1</number>
|
||||
@ -278,7 +278,7 @@
|
||||
<number>4</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>100</number>
|
||||
<number>240</number>
|
||||
</property>
|
||||
<property name="pageStep">
|
||||
<number>1</number>
|
||||
@ -370,7 +370,7 @@
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Display live spectrum</string>
|
||||
<string>Display max hold</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Max Hold</string>
|
||||
@ -390,6 +390,41 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ButtonSwitch" name="current">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>24</width>
|
||||
<height>24</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Display live spectrum</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Max Hold</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset resource="../resources/res.qrc">
|
||||
<normaloff>:/current.png</normaloff>:/current.png</iconset>
|
||||
</property>
|
||||
<property name="iconSize">
|
||||
<size>
|
||||
<width>16</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ButtonSwitch" name="invert">
|
||||
<property name="sizePolicy">
|
||||
|
BIN
sdrbase/resources/current.png
Normal file
BIN
sdrbase/resources/current.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 742 B |
@ -22,5 +22,6 @@
|
||||
<file>display2_w.png</file>
|
||||
<file>horizontal_w.png</file>
|
||||
<file>vertical_w.png</file>
|
||||
<file>current.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
Loading…
Reference in New Issue
Block a user