• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mcallegari / qlcplus / 13633248611

03 Mar 2025 02:31PM UTC coverage: 31.871% (+0.4%) from 31.5%
13633248611

push

github

web-flow
actions: add chrpath to profile

14689 of 46089 relevant lines covered (31.87%)

26426.11 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/ui/src/audiobar.cpp
1
/*
2
  Q Light Controller Plus
3
  audiobar.cpp
4

5
  Copyright (c) Massimo Callegari
6

7
  Licensed under the Apache License, Version 2.0 (the "License");
8
  you may not use this file except in compliance with the License.
9
  You may obtain a copy of the License at
10

11
      http://www.apache.org/licenses/LICENSE-2.0.txt
12

13
  Unless required by applicable law or agreed to in writing, software
14
  distributed under the License is distributed on an "AS IS" BASIS,
15
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
  See the License for the specific language governing permissions and
17
  limitations under the License.
18
*/
19

20
#include <QXmlStreamReader>
21
#include <QXmlStreamWriter>
22
#include <QDebug>
23

24
#include "audiobar.h"
25
#include "vcbutton.h"
26
#include "vcslider.h"
27
#include "vcspeeddial.h"
28
#include "vccuelist.h"
29
#include "virtualconsole.h"
30

31
AudioBar::AudioBar(int t, uchar v, quint32 parentId)
×
32
{
33
    m_parentId = parentId;
×
34
    m_type = t;
×
35
    m_value = v;
×
36
    m_tapped = false;
×
37
    m_dmxChannels.clear();
×
38
    m_absDmxChannels.clear();
×
39
    m_function = NULL;
×
40
    m_widget = NULL;
×
41
    m_widgetID = VCWidget::invalidId();
×
42
    m_minThreshold = 51; // 20%
×
43
    m_maxThreshold = 204; // 80%
×
44
    m_divisor = 1;
×
45
    m_skippedBeats = 0;
×
46
}
×
47

48
AudioBar *AudioBar::createCopy()
×
49
{
50
    AudioBar *copy = new AudioBar();
×
51
    copy->m_parentId = m_parentId;
×
52
    copy->m_type = m_type;
×
53
    copy->m_value = m_value;
×
54
    copy->m_name = m_name;
×
55
    copy->m_tapped = m_tapped;
×
56
    copy->m_dmxChannels = m_dmxChannels;
×
57
    copy->m_absDmxChannels = m_absDmxChannels;
×
58
    copy->m_function = m_function;
×
59
    copy->m_widget = m_widget;
×
60
    copy->m_widgetID = m_widgetID;
×
61
    copy->m_minThreshold = m_minThreshold;
×
62
    copy->m_maxThreshold = m_maxThreshold;
×
63
    copy->m_divisor = m_divisor;
×
64
    copy->m_skippedBeats = m_skippedBeats;
×
65

66
    return copy;
×
67
}
68

69
void AudioBar::setName(QString nme)
×
70
{
71
    m_name = nme;
×
72
}
×
73

74
void AudioBar::setType(int type)
×
75
{
76
    m_type = type;
×
77
    if (m_type == None)
×
78
    {
79
        m_value = 0;
×
80
        m_tapped = false;
×
81
        m_dmxChannels.clear();
×
82
        m_absDmxChannels.clear();
×
83
        m_function = NULL;
×
84
        m_widget = NULL;
×
85
        m_widgetID = VCWidget::invalidId();
×
86
        m_minThreshold = 51; // 20%
×
87
        m_maxThreshold = 204; // 80%
×
88
        m_divisor = 1;
×
89
        m_skippedBeats = 0;
×
90
    }
91
}
×
92

93
void AudioBar::setMinThreshold(uchar value)
×
94
{
95
    m_minThreshold = value;
×
96
}
×
97

98
void AudioBar::setMaxThreshold(uchar value)
×
99
{
100
    m_maxThreshold = value;
×
101
}
×
102

103
void AudioBar::setDivisor(int value)
×
104
{
105
    m_divisor = value;
×
106
    if (m_skippedBeats >= m_divisor)
×
107
        m_skippedBeats = 0;
×
108
}
×
109

110
void AudioBar::attachDmxChannels(Doc *doc, QList<SceneValue> list)
×
111
{
112
    m_dmxChannels.clear();
×
113
    m_dmxChannels = list;
×
114
    m_absDmxChannels.clear();
×
115
    foreach (SceneValue scv, m_dmxChannels)
×
116
    {
117
        Fixture *fx = doc->fixture(scv.fxi);
×
118
        if (fx != NULL)
×
119
        {
120
            quint32 absAddr = fx->universeAddress() + scv.channel;
×
121
            m_absDmxChannels.append(absAddr);
×
122
        }
123
    }
×
124
}
×
125

126
void AudioBar::attachFunction(Function *func)
×
127
{
128
    if (func != NULL)
×
129
    {
130
        qDebug() << Q_FUNC_INFO << "Attaching function:" << func->name();
131
        m_function = func;
×
132
    }
133
}
×
134

135
void AudioBar::attachWidget(quint32 wID)
×
136
{
137
    if (wID == VCWidget::invalidId())
×
138
        return;
139

140
    qDebug() << Q_FUNC_INFO << "Attaching widget with ID" << wID;
141
    m_widgetID = wID;
×
142
    m_widget = NULL;
×
143
    m_tapped = false;
×
144
}
145

146
VCWidget *AudioBar::widget()
×
147
{
148
    if (m_widget == NULL)
×
149
        m_widget = VirtualConsole::instance()->widget(m_widgetID);
×
150

151
    return m_widget;
×
152
}
153

154
void AudioBar::checkFunctionThresholds(Doc *doc)
×
155
{
156
    if (m_function == NULL)
×
157
        return;
158
    if (m_value >= m_maxThreshold)
×
159
    {
160
        m_function->start(doc->masterTimer(), functionParent());
×
161
    }
162
    else if (m_value < m_minThreshold)
×
163
    {
164
        m_function->stop(functionParent());
×
165
    }
166
}
167

168
void AudioBar::checkWidgetFunctionality()
×
169
{
170
    if (m_widgetID == VCWidget::invalidId())
×
171
        return;
172

173
    if (widget() == NULL) // fills m_widget if needed
×
174
        return;
175

176
    if (m_widget->type() == VCWidget::ButtonWidget)
×
177
    {
178
        VCButton *btn = (VCButton *)m_widget;
×
179
        if (m_value >= m_maxThreshold && btn->state() == VCButton::Inactive)
×
180
        {
181
            btn->pressFunction();
×
182
            //btn->setState(true);
183
        }
184
        else if (m_value < m_minThreshold && btn->state() != VCButton::Inactive)
×
185
        {
186
            btn->pressFunction();
×
187
            btn->releaseFunction(); // finish flashing
×
188
            //btn->setState(false);
189
        }
190
    }
191
    else if (m_widget->type() == VCWidget::SliderWidget)
×
192
    {
193
        VCSlider *slider = (VCSlider *)m_widget;
×
194
        slider->setSliderValue(m_value, true, true);
×
195
    }
196
    else if (m_widget->type() == VCWidget::SpeedDialWidget)
×
197
    {
198
        VCSpeedDial *speedDial = (VCSpeedDial *)m_widget;
×
199
        if (m_value >= m_maxThreshold && !m_tapped)
×
200
        {
201
            if (m_skippedBeats == 0)
×
202
               speedDial->tap();
×
203

204
            m_tapped = true;
×
205
            m_skippedBeats = (m_skippedBeats + 1) % m_divisor;
×
206
        }
207
        else if (m_value < m_minThreshold)
×
208
        {
209
            m_tapped = false;
×
210
        }
211
    }
212
    else if (m_widget->type() == VCWidget::CueListWidget)
×
213
    {
214
        VCCueList *cueList = (VCCueList *)m_widget;
×
215
        if (m_value >= m_maxThreshold && !m_tapped)
×
216
        {
217
            if (m_skippedBeats == 0)
×
218
                cueList->slotNextCue();
×
219

220
            m_tapped = true;
×
221
            m_skippedBeats = (m_skippedBeats + 1) % m_divisor;
×
222
        }
223
        else if (m_value < m_minThreshold)
×
224
            m_tapped = false;
×
225
    }
226
}
227

228
void AudioBar::debugInfo()
×
229
{
230
    qDebug() << "[AudioBar] " << m_name;
231
    qDebug() << "   type:" << m_type << ", value:" << m_value;
232

233
}
×
234

235
bool AudioBar::loadXML(QXmlStreamReader &root, Doc *doc)
×
236
{
237
    QXmlStreamAttributes attrs = root.attributes();
×
238

239
    if (attrs.hasAttribute(KXMLQLCAudioBarName))
×
240
        m_name = attrs.value(KXMLQLCAudioBarName).toString();
×
241

242
    if (attrs.hasAttribute(KXMLQLCAudioBarType))
×
243
    {
244
        m_type = attrs.value(KXMLQLCAudioBarType).toString().toInt();
×
245
        m_minThreshold = attrs.value(KXMLQLCAudioBarMinThreshold).toString().toInt();
×
246
        m_maxThreshold = attrs.value(KXMLQLCAudioBarMaxThreshold).toString().toInt();
×
247
        m_divisor = attrs.value(KXMLQLCAudioBarDivisor).toString().toInt();
×
248

249
        switch(m_type)
×
250
        {
251
            case AudioBar::FunctionBar:
×
252
            {
253
                if (attrs.hasAttribute(KXMLQLCAudioBarFunction))
×
254
                {
255
                    quint32 fid = attrs.value(KXMLQLCAudioBarFunction).toString().toUInt();
×
256
                    Function *func = doc->function(fid);
×
257
                    if (func != NULL)
×
258
                        m_function = func;
×
259
                }
260
            }
261
            break;
262
            case AudioBar::VCWidgetBar:
×
263
            {
264
                if (attrs.hasAttribute(KXMLQLCAudioBarWidget))
×
265
                {
266
                    quint32 wid = attrs.value(KXMLQLCAudioBarWidget).toString().toUInt();
×
267
                    m_widgetID = wid;
×
268
                }
269
            }
270
            break;
271
            case AudioBar::DMXBar:
×
272
            {
273
                QXmlStreamReader::TokenType tType = root.readNext();
×
274

275
                if (tType == QXmlStreamReader::EndElement)
×
276
                {
277
                    root.readNext();
×
278
                    return true;
279
                }
280

281
                if (tType == QXmlStreamReader::Characters)
×
282
                    root.readNext();
×
283

284
                if (root.name() == KXMLQLCAudioBarDMXChannels)
×
285
                {
286
                    QString dmxValues = root.readElementText();
×
287
                    if (dmxValues.isEmpty() == false)
×
288
                    {
289
                        QList<SceneValue> channels;
290
                        QStringList varray = dmxValues.split(",");
×
291
                        for (int i = 0; i < varray.count(); i+=2)
×
292
                        {
293
                            channels.append(SceneValue(QString(varray.at(i)).toUInt(),
×
294
                                                         QString(varray.at(i + 1)).toUInt(), 0));
×
295
                        }
296
                        attachDmxChannels(doc, channels);
×
297
                    }
×
298
                }
×
299
            }
300
            break;
301
        }
302
    }
303

304
    root.skipCurrentElement();
×
305

306
    return true;
307
}
308

309
bool AudioBar::saveXML(QXmlStreamWriter *doc, QString tagName, int index)
×
310
{
311
    Q_ASSERT(doc != NULL);
312

313
    qDebug() << Q_FUNC_INFO;
314

315
    doc->writeStartElement(tagName);
×
316
    doc->writeAttribute(KXMLQLCAudioBarName, m_name);
×
317
    doc->writeAttribute(KXMLQLCAudioBarType, QString::number(m_type));
×
318
    doc->writeAttribute(KXMLQLCAudioBarMinThreshold, QString::number(m_minThreshold));
×
319
    doc->writeAttribute(KXMLQLCAudioBarMaxThreshold, QString::number(m_maxThreshold));
×
320
    doc->writeAttribute(KXMLQLCAudioBarDivisor, QString::number(m_divisor));
×
321
    doc->writeAttribute(KXMLQLCAudioBarIndex, QString::number(index));
×
322

323
    if (m_type == AudioBar::DMXBar && m_dmxChannels.count() > 0)
×
324
    {
325
        QString chans;
326
        foreach (SceneValue scv, m_dmxChannels)
×
327
        {
328
            if (chans.isEmpty() == false)
×
329
                chans.append(",");
×
330
            chans.append(QString("%1,%2").arg(scv.fxi).arg(scv.channel));
×
331
        }
×
332
        if (chans.isEmpty() == false)
×
333
        {
334
            doc->writeTextElement(KXMLQLCAudioBarDMXChannels, chans);
×
335
        }
336
    }
×
337
    else if (m_type == AudioBar::FunctionBar && m_function != NULL)
×
338
    {
339
        doc->writeAttribute(KXMLQLCAudioBarFunction, QString::number(m_function->id()));
×
340
    }
341
    else if (m_type == AudioBar::VCWidgetBar && m_widgetID != VCWidget::invalidId())
×
342
    {
343
        doc->writeAttribute(KXMLQLCAudioBarWidget, QString::number(m_widgetID));
×
344
    }
345

346
    /* End <tagName> tag */
347
    doc->writeEndElement();
×
348

349
    return true;
×
350
}
351

352
FunctionParent AudioBar::functionParent() const
×
353
{
354
    if (m_parentId != quint32(-1))
×
355
        return FunctionParent(FunctionParent::AutoVCWidget, m_parentId);
×
356
    else
357
        return FunctionParent::master();
358
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc