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

mcallegari / qlcplus / 19409821768

16 Nov 2025 06:06PM UTC coverage: 34.233% (-0.01%) from 34.243%
19409821768

push

github

mcallegari
vc/soloframe: add an option to exclude functions monitored by buttons to be stopped

3 of 38 new or added lines in 9 files covered. (7.89%)

2 existing lines in 2 files now uncovered.

17724 of 51774 relevant lines covered (34.23%)

19630.45 hits per line

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

0.0
/ui/src/virtualconsole/vcaudiotriggers.cpp
1
/*
2
  Q Light Controller Plus
3
  vcaudiotriggers.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 <QMessageBox>
23
#include <QSettings>
24
#include <QDebug>
25

26
#include "vcaudiotriggersproperties.h"
27
#include "vcpropertieseditor.h"
28
#include "vcaudiotriggers.h"
29
#include "audiocapture.h"
30
#include "genericfader.h"
31
#include "fadechannel.h"
32
#include "universe.h"
33
#include "audiobar.h"
34
#include "apputil.h"
35
#include "doc.h"
36

37
#define KXMLQLCVCATKey          QStringLiteral("Key")
38
#define KXMLQLCVCATBarsNumber   QStringLiteral("BarsNumber")
39

40
#define KXMLQLCVolumeBar    QStringLiteral("VolumeBar")
41
#define KXMLQLCSpectrumBar  QStringLiteral("SpectrumBar")
42

43
const QSize VCAudioTriggers::defaultSize(QSize(300, 200));
44

45
VCAudioTriggers::VCAudioTriggers(QWidget* parent, Doc* doc)
×
46
    : VCWidget(parent, doc)
47
    , m_hbox(NULL)
×
48
    , m_button(NULL)
×
49
    , m_label(NULL)
×
50
    , m_spectrum(NULL)
×
51
    , m_volumeSlider(NULL)
×
52
    , m_inputCapture(NULL)
×
53
{
54
    /* Set the class name "VCAudioTriggers" as the object name as well */
55
    setObjectName(VCAudioTriggers::staticMetaObject.className());
×
56

57
    setType(VCWidget::AudioTriggersWidget);
×
58
    setFrameStyle(KVCFrameStyleSunken);
×
59

60
    new QVBoxLayout(this);
×
61

62
    /* Main HBox */
63
    m_hbox = new QHBoxLayout();
×
64
    m_hbox->setGeometry(QRect(0, 0, 300, 40));
×
65

66
    layout()->setSpacing(2);
×
67
    layout()->setContentsMargins(4, 4, 4, 4);
×
68
    layout()->addItem(m_hbox);
×
69

70
    m_button = new QToolButton(this);
×
71
    m_button->setStyle(AppUtil::saneStyle());
×
72
    m_button->setIconSize(QSize(32, 32));
×
73
    m_button->setMinimumSize(QSize(32, 32));
×
74
    m_button->setMaximumSize(QSize(32, 32));
×
75
    m_button->setIcon(QIcon(":/check.png"));
×
76
    m_button->setCheckable(true);
×
77
    QString btnSS = "QToolButton { background-color: #E0DFDF; border: 1px solid gray; border-radius: 3px; padding: 3px; } ";
×
78
    btnSS += "QToolButton:checked { background-color: #D7DE75; border: 1px solid gray; border-radius: 3px; padding: 3px; } ";
×
79
    m_button->setStyleSheet(btnSS);
×
80
    m_button->setEnabled(false);
×
81

82
    m_hbox->addWidget(m_button);
×
83
    connect(m_button, SIGNAL(toggled(bool)), this, SLOT(slotEnableButtonToggled(bool)));
×
84

85
    m_label = new QLabel(this);
×
86
    m_label->setText(this->caption());
×
87
    QString txtColor = "white";
×
88
    if (m_hasCustomForegroundColor)
×
89
        txtColor = this->foregroundColor().name();
×
90
    m_label->setStyleSheet("QLabel { background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #345D27, stop: 1 #0E1A0A); "
×
91
                           "color: " + txtColor + "; border-radius: 3px; padding: 3px; margin-left: 2px; }");
×
92

93
    if (m_hasCustomFont)
×
94
        m_label->setFont(font());
×
95
    else
96
    {
97
        QFont m_font = QApplication::font();
×
98
        m_font.setBold(true);
×
99
        m_font.setPixelSize(12);
×
100
        m_label->setFont(m_font);
×
101
    }
×
102
    m_hbox->addWidget(m_label);
×
103

104
    QSharedPointer<AudioCapture> capture(m_doc->audioInputCapture());
×
105
    m_inputCapture = capture.data();
×
106

107
    // create the  AudioBar items to hold the spectrum data.
108
    // To be loaded from the project
109
    m_volumeBar = new AudioBar(AudioBar::None, 0, id());
×
110
    m_spectrumBars.reserve(m_inputCapture->defaultBarsNumber());
×
111
    for (int i = 0; i < m_inputCapture->defaultBarsNumber(); i++)
×
112
    {
113
        AudioBar *asb = new AudioBar(AudioBar::None, 0, id());
×
114
        m_spectrumBars.append(asb);
×
115
    }
116

117
    QHBoxLayout *hbox2 = new QHBoxLayout();
×
118
    m_volumeSlider = new ClickAndGoSlider(this);
×
119
    m_volumeSlider->setOrientation(Qt::Vertical);
×
120
    m_volumeSlider->setRange(0, 100);
×
121
    m_volumeSlider->setSliderStyleSheet(CNG_DEFAULT_STYLE);
×
122
    m_volumeSlider->setValue(100);
×
123
    m_volumeSlider->setFixedWidth(32);
×
124
    m_volumeSlider->setEnabled(false);
×
125

126
    connect(m_volumeSlider, SIGNAL(valueChanged(int)),
×
127
            this, SLOT(slotVolumeChanged(int)));
128

129
    m_spectrum = new AudioTriggerWidget(this);
×
130
    m_spectrum->setBarsNumber(m_inputCapture->defaultBarsNumber());
×
131
    m_spectrum->setMaxFrequency(AudioCapture::maxFrequency());
×
132
    m_spectrum->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
×
133

134
    layout()->addItem(hbox2);
×
135
    hbox2->addWidget(m_spectrum);
×
136
    hbox2->addWidget(m_volumeSlider);
×
137

138
    /* Initial size */
139
    QSettings settings;
×
140
    QVariant var = settings.value(SETTINGS_AUDIOTRIGGERS_SIZE);
×
141
    if (var.isValid() == true)
×
142
        resize(var.toSize());
×
143
    else
144
        resize(defaultSize);
×
145

146
    slotModeChanged(m_doc->mode());
×
147
}
×
148

149
VCAudioTriggers::~VCAudioTriggers()
×
150
{
151
    QSharedPointer<AudioCapture> capture(m_doc->audioInputCapture());
×
152

153
    if (m_inputCapture == capture.data())
×
154
        m_inputCapture->unregisterBandsNumber(m_spectrum->barsNumber());
×
155

156
    qDeleteAll(m_spectrumBars);
×
157
    delete m_volumeBar;
×
158
}
×
159

160
void VCAudioTriggers::enableWidgetUI(bool enable)
×
161
{
162
    if (m_button)
×
163
        m_button->setEnabled(enable);
×
164

165
    m_volumeSlider->setEnabled(enable);
×
166
}
×
167

NEW
168
void VCAudioTriggers::notifyFunctionStarting(quint32 fid, qreal intensity, bool excludeMonitored)
×
169
{
170
    // Stop on any other function started
171
    Q_UNUSED(fid)
172
    Q_UNUSED(intensity)
173
    Q_UNUSED(excludeMonitored)
174

175
    if (m_button->isChecked() == true)
×
176
        enableCapture(false);
×
177
}
×
178

179
void VCAudioTriggers::enableCapture(bool enable)
×
180
{
181
    // in case the audio input device has been changed in the meantime...
182
    QSharedPointer<AudioCapture> capture(m_doc->audioInputCapture());
×
183
    bool captureIsNew = m_inputCapture != capture.data();
×
184
    m_inputCapture = capture.data();
×
185

186
    if (enable == true)
×
187
    {
188
        connect(m_inputCapture, SIGNAL(dataProcessed(double*,int,double,quint32)),
×
189
                this, SLOT(slotDisplaySpectrum(double*,int,double,quint32)));
190
        connect(m_inputCapture, SIGNAL(volumeChanged(int)),
×
191
                this, SLOT(slotUpdateVolumeSlider(int)));
192
        m_inputCapture->registerBandsNumber(m_spectrum->barsNumber());
×
193

194
        m_button->blockSignals(true);
×
195
        m_button->setChecked(true);
×
196
        m_button->blockSignals(false);
×
197

198
        emit captureEnabled(true);
×
199

200
        // Invalid ID: Stop every other widget
201
        emit functionStarting(Function::invalidId());
×
202
    }
203
    else
204
    {
205
        if (!captureIsNew)
×
206
        {
207
            m_inputCapture->unregisterBandsNumber(m_spectrum->barsNumber());
×
208
            disconnect(m_inputCapture, SIGNAL(dataProcessed(double*,int,double,quint32)),
×
209
                       this, SLOT(slotDisplaySpectrum(double*,int,double,quint32)));
210
            disconnect(m_inputCapture, SIGNAL(volumeChanged(int)),
×
211
                       this, SLOT(slotUpdateVolumeSlider(int)));
212
        }
213

214
        m_button->blockSignals(true);
×
215
        m_button->setChecked(false);
×
216
        m_button->blockSignals(false);
×
217

218
        emit captureEnabled(false);
×
219
    }
220
}
×
221

222
void VCAudioTriggers::toggleEnableButton(bool toggle)
×
223
{
224
    if (mode() == Doc::Design)
×
225
        return;
×
226

227
    if (m_button)
×
228
        m_button->setChecked(toggle);
×
229
}
230

231
void VCAudioTriggers::slotEnableButtonToggled(bool toggle)
×
232
{
233
    if (mode() == Doc::Design)
×
234
        return;
×
235

236
    enableCapture(toggle);
×
237
    updateFeedback();
×
238
}
239

240
void VCAudioTriggers::slotDisplaySpectrum(double *spectrumBands, int size,
×
241
                                          double maxMagnitude, quint32 power)
242
{
243
    //qDebug() << "Display spectrum ----- bars:" << size;
244
    if (size != m_spectrum->barsNumber())
×
245
        return;
×
246

247
    m_spectrum->displaySpectrum(spectrumBands, maxMagnitude, power);
×
248
    m_volumeBar->m_value = m_spectrum->getUcharVolume();
×
249

250
    if (mode() == Doc::Design)
×
251
        return;
×
252

253
    if (m_volumeBar->m_type == AudioBar::FunctionBar)
×
254
        m_volumeBar->checkFunctionThresholds(m_doc);
×
255
    else if (m_volumeBar->m_type == AudioBar::VCWidgetBar)
×
256
        m_volumeBar->checkWidgetFunctionality();
×
257

258
    for (int i = 0; i < m_spectrumBars.count(); i++)
×
259
    {
260
        m_spectrumBars[i]->m_value = m_spectrum->getUcharBand(i);
×
261
        if (m_spectrumBars[i]->m_type == AudioBar::FunctionBar)
×
262
            m_spectrumBars[i]->checkFunctionThresholds(m_doc);
×
263
        else if (m_spectrumBars[i]->m_type == AudioBar::VCWidgetBar)
×
264
            m_spectrumBars[i]->checkWidgetFunctionality();
×
265
    }
266
}
267

268
void VCAudioTriggers::slotVolumeChanged(int volume)
×
269
{
270
    m_doc->audioInputCapture()->setVolume(intensity() * qreal(volume) / 100.0);
×
271
}
×
272

273
void VCAudioTriggers::slotUpdateVolumeSlider(int volume)
×
274
{
275
    m_volumeSlider->setValue(volume);
×
276
}
×
277

278
/*********************************************************************
279
 * DMXSource
280
 *********************************************************************/
281

282
void VCAudioTriggers::writeDMX(MasterTimer *timer, QList<Universe *> universes)
×
283
{
284
    Q_UNUSED(timer);
285

286
    if (mode() == Doc::Design)
×
287
        return;
×
288

289
    quint32 lastUniverse = Universe::invalid();
×
290
    QSharedPointer<GenericFader> fader;
×
291

292
    if (m_volumeBar->m_type == AudioBar::DMXBar)
×
293
    {
294
        for (int i = 0; i < m_volumeBar->m_absDmxChannels.count(); i++)
×
295
        {
296
            int absAddress = m_volumeBar->m_absDmxChannels.at(i);
×
297
            //quint32 address = absAddress & 0x01FF;
298
            quint32 universe = absAddress >> 9;
×
299
            if (universe != lastUniverse)
×
300
            {
301
                fader = m_fadersMap.value(universe, QSharedPointer<GenericFader>());
×
302
                if (fader.isNull())
×
303
                {
304
                    fader = universes[universe]->requestFader();
×
305
                    fader->adjustIntensity(intensity());
×
306
                    m_fadersMap[universe] = fader;
×
307
                }
308
                lastUniverse = universe;
×
309
                fader->setEnabled(m_button->isChecked() ? true : false);
×
310
            }
311

312
            FadeChannel *fc = fader->getChannelFader(m_doc, universes[universe], Fixture::invalidId(), absAddress);           
×
313
            fc->setStart(fc->current());
×
314
            fc->setTarget(m_volumeBar->m_value);
×
315
            fc->setReady(false);
×
316
            fc->setElapsed(0);
×
317
        }
318
    }
319
    foreach (AudioBar *sb, m_spectrumBars)
×
320
    {
321
        if (sb->m_type == AudioBar::DMXBar)
×
322
        {
323
            for (int i = 0; i < sb->m_absDmxChannels.count(); i++)
×
324
            {
325
                int absAddress = sb->m_absDmxChannels.at(i);
×
326
                //quint32 address = absAddress & 0x01FF;
327
                quint32 universe = absAddress >> 9;
×
328
                if (universe != lastUniverse)
×
329
                {
330
                    fader = m_fadersMap.value(universe, QSharedPointer<GenericFader>());
×
331
                    if (fader == NULL)
×
332
                    {
333
                        fader = universes[universe]->requestFader();
×
334
                        fader->adjustIntensity(intensity());
×
335
                        m_fadersMap[universe] = fader;
×
336
                    }
337
                    fader->setEnabled(m_button->isChecked() ? true : false);
×
338
                    lastUniverse = universe;
×
339
                }
340

341
                FadeChannel *fc = fader->getChannelFader(m_doc, universes[universe], Fixture::invalidId(), absAddress);
×
342
                fc->setStart(fc->current());
×
343
                fc->setTarget(sb->m_value);
×
344
                fc->setReady(false);
×
345
                fc->setElapsed(0);
×
346
            }
347
        }
348
    }
×
349
}
×
350

351
/*********************************************************************
352
 * Key sequence handler
353
 *********************************************************************/
354

355
void VCAudioTriggers::setKeySequence(const QKeySequence& keySequence)
×
356
{
357
    m_keySequence = QKeySequence(keySequence);
×
358
}
×
359

360
QKeySequence VCAudioTriggers::keySequence() const
×
361
{
362
    return m_keySequence;
×
363
}
364

365
void VCAudioTriggers::slotKeyPressed(const QKeySequence& keySequence)
×
366
{
367
    if (acceptsInput() == false)
×
368
        return;
×
369

370
    if (m_keySequence == keySequence)
×
371
    {
372
        if (m_button->isChecked())
×
373
            slotEnableButtonToggled(false);
×
374
        else
375
            slotEnableButtonToggled(true);
×
376
    }
377
}
378

379
void VCAudioTriggers::updateFeedback()
×
380
{
381
    QSharedPointer<QLCInputSource> src = inputSource();
×
382
    if (!src.isNull() && src->isValid() == true)
×
383
    {
384
        if (m_button->isChecked())
×
385
            sendFeedback(src->feedbackValue(QLCInputFeedback::UpperValue));
×
386
        else
387
            sendFeedback(src->feedbackValue(QLCInputFeedback::LowerValue));
×
388
    }
389
}
×
390

391
void VCAudioTriggers::slotInputValueChanged(quint32 universe, quint32 channel, uchar value)
×
392
{
393
    /* Don't let input data through in design mode or if disabled */
394
    if (acceptsInput() == false)
×
395
        return;
×
396

397
    if (checkInputSource(universe, (page() << 16) | channel, value, sender()) && value > 0)
×
398
    {
399
        if (m_button->isChecked())
×
400
            slotEnableButtonToggled(false);
×
401
        else
402
            slotEnableButtonToggled(true);
×
403
    }
404
}
405

406
/*********************************************************************
407
 * Clipboard
408
 *********************************************************************/
409

410
VCWidget *VCAudioTriggers::createCopy(VCWidget *parent)
×
411
{
412
    Q_ASSERT(parent != NULL);
×
413

414
    VCAudioTriggers* triggers = new VCAudioTriggers(parent, m_doc);
×
415
    if (triggers->copyFrom(this) == false)
×
416
    {
417
        delete triggers;
×
418
        triggers = NULL;
×
419
    }
420

421
    return triggers;
×
422
}
423

424
bool VCAudioTriggers::copyFrom(const VCWidget *widget)
×
425
{
426
    const VCAudioTriggers* triggers = qobject_cast <const VCAudioTriggers*> (widget);
×
427
    if (triggers == NULL)
×
428
        return false;
×
429

430
    /* TODO: Copy triggers-specific stuff */
431

432
    /* Copy common stuff */
433
    return VCWidget::copyFrom(widget);
×
434
}
435

436
/*************************************************************************
437
 * VCWidget-inherited
438
 *************************************************************************/
439

440
void VCAudioTriggers::setCaption(const QString &text)
×
441
{
442
    if (m_label != NULL)
×
443
        m_label->setText(text);
×
444

445
    VCWidget::setCaption(text);
×
446
}
×
447

448
void VCAudioTriggers::setForegroundColor(const QColor &color)
×
449
{
450
    if (m_label != NULL)
×
451
    {
452
        m_label->setStyleSheet("QLabel { background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #345D27, stop: 1 #0E1A0A); "
×
453
                               "color: " + color.name() + "; border-radius: 3px; padding: 3px; margin-left: 2px; }");
×
454
        m_hasCustomForegroundColor = true;
×
455
        m_doc->setModified();
×
456
    }
457
}
×
458

459
QColor VCAudioTriggers::foregroundColor() const
×
460
{
461
    if (m_label != NULL)
×
462
        return m_label->palette().color(m_label->foregroundRole());
×
463
    else
464
        return VCWidget::foregroundColor();
×
465
}
466

467
void VCAudioTriggers::slotModeChanged(Doc::Mode mode)
×
468
{
469
    if (mode == Doc::Operate)
×
470
    {
471
        enableWidgetUI(true);
×
472

473
        foreach (AudioBar *bar, getAudioBars())
×
474
        {
475
            if (bar->m_type == AudioBar::DMXBar)
×
476
            {
477
                m_doc->masterTimer()->registerDMXSource(this);
×
478
                break;
×
479
            }
480
        }
×
481
    }
482
    else
483
    {
484
        enableWidgetUI(false);
×
485
        enableCapture(false);
×
486
        m_doc->masterTimer()->unregisterDMXSource(this);
×
487

488
        // request to delete all the active faders
489
        foreach (QSharedPointer<GenericFader> fader, m_fadersMap)
×
490
        {
491
            if (!fader.isNull())
×
492
                fader->requestDelete();
×
493
        }
×
494
        m_fadersMap.clear();
×
495
    }
496
    VCWidget::slotModeChanged(mode);
×
497
}
×
498

499
/*************************************************************************
500
 * Configuration
501
 *************************************************************************/
502

503
AudioBar *VCAudioTriggers::getSpectrumBar(int index)
×
504
{
505
    if (index == volumeBarIndex())
×
506
        return m_volumeBar;
×
507
    if (index >= 0 && index < m_spectrumBars.size())
×
508
        return m_spectrumBars.at(index);
×
509

510
    return NULL;
×
511
}
512

513
QList<AudioBar *> VCAudioTriggers::getAudioBars()
×
514
{
515
    QList <AudioBar *> list;
×
516
    list.reserve(1 + m_spectrumBars.size());
×
517
    list.append(m_volumeBar);
×
518
    list.append(m_spectrumBars);
×
519

520
    return list;
×
521
}
×
522

523
void VCAudioTriggers::setSpectrumBarsNumber(int num)
×
524
{
525
    if (num > m_spectrumBars.count())
×
526
    {
527
        int barsToAdd = num - m_spectrumBars.count();
×
528
        for (int i = 0 ; i < barsToAdd; i++)
×
529
        {
530
            AudioBar *asb = new AudioBar(AudioBar::None, 0, id());
×
531
            m_spectrumBars.append(asb);
×
532
        }
533
    }
534
    else if (num < m_spectrumBars.count())
×
535
    {
536
        int barsToRemove = m_spectrumBars.count() - num;
×
537
        for (int i = 0 ; i < barsToRemove; i++)
×
538
            delete m_spectrumBars.takeLast();
×
539
    }
540

541
    if (m_spectrum != NULL)
×
542
        m_spectrum->setBarsNumber(num);
×
543
}
×
544

545
void VCAudioTriggers::setSpectrumBarType(int index, int type)
×
546
{
547
    if (index == volumeBarIndex())
×
548
    {
549
        m_volumeBar->setType(type);
×
550
        return;
×
551
    }
552
    if (index >= 0 && index < m_spectrumBars.size())
×
553
    {
554
        m_spectrumBars[index]->setType(type);
×
555
    }
556
}
557

558
void VCAudioTriggers::editProperties()
×
559
{
560
    // make a backup copy of the current bars
561
    AudioBar *tmpVolume = m_volumeBar->createCopy();
×
562
    QList <AudioBar *> tmpSpectrumBars;
×
563
    foreach (AudioBar *bar, m_spectrumBars)
×
564
        tmpSpectrumBars.append(bar->createCopy());
×
565
    int barsNumber = m_spectrumBars.count();
×
566

567
    AudioTriggersConfiguration atc(this, m_doc, barsNumber, AudioCapture::maxFrequency());
×
568

569
    if (atc.exec() == QDialog::Rejected)
×
570
    {
571
        // restore the previous bars backup
572
        delete m_volumeBar;
×
573
        m_volumeBar = tmpVolume;
×
574
        qDeleteAll(m_spectrumBars);
×
575
        m_spectrumBars.clear();
×
576
        foreach (AudioBar *bar, tmpSpectrumBars)
×
577
            m_spectrumBars.append(bar);
×
578
    }
579

580
    m_spectrum->setBarsNumber(m_spectrumBars.count());
×
581

582
    if (barsNumber != m_spectrumBars.count())
×
583
    {
584
        QSharedPointer<AudioCapture> capture(m_doc->audioInputCapture());
×
585
        bool captureIsNew = m_inputCapture != capture.data();
×
586
        m_inputCapture = capture.data();
×
587

588
        if (m_button->isChecked())
×
589
        {
590
            if (!captureIsNew)
×
591
                m_inputCapture->unregisterBandsNumber(barsNumber);
×
592

593
            m_inputCapture->registerBandsNumber(m_spectrumBars.count());
×
594

595
            if (captureIsNew)
×
596
            {
597
                connect(m_inputCapture, SIGNAL(dataProcessed(double*,int,double,quint32)),
×
598
                        this, SLOT(slotDisplaySpectrum(double*,int,double,quint32)));
599
                connect(m_inputCapture, SIGNAL(volumeChanged(qreal)),
×
600
                        this, SLOT(slotUpdateVolumeSlider(int)));
601
            }
602
        }
603
    }
×
604
}
×
605

606
void VCAudioTriggers::adjustIntensity(qreal val)
×
607
{
608
    VCWidget::adjustIntensity(val);
×
609
    slotVolumeChanged(m_volumeSlider->value());
×
610
}
×
611

612
/*********************************************************************
613
 * Load & Save
614
 *********************************************************************/
615

616
bool VCAudioTriggers::loadXML(QXmlStreamReader &root)
×
617
{
618
    if (root.name() != KXMLQLCVCAudioTriggers)
×
619
    {
620
        qWarning() << Q_FUNC_INFO << "Audio Triggers node not found";
×
621
        return false;
×
622
    }
623
    if (root.attributes().hasAttribute(KXMLQLCVCATBarsNumber))
×
624
    {
625
        int barsNum = root.attributes().value(KXMLQLCVCATBarsNumber).toString().toInt();
×
626
        setSpectrumBarsNumber(barsNum);
×
627
    }
628

629
    /* Widget commons */
630
    loadXMLCommon(root);
×
631

632
    /* Children */
633
    while (root.readNextStartElement())
×
634
    {
635
        //qDebug() << "VC Audio triggers tag:" << root.name();
636
        QXmlStreamAttributes attrs = root.attributes();
×
637

638
        if (root.name() == KXMLQLCWindowState)
×
639
        {
640
            int x = 0, y = 0, w = 0, h = 0;
×
641
            bool visible = false;
×
642
            loadXMLWindowState(root, &x, &y, &w, &h, &visible);
×
643
            setGeometry(x, y, w, h);
×
644
        }
645
        else if (root.name() == KXMLQLCVCWidgetAppearance)
×
646
        {
647
            loadXMLAppearance(root);
×
648
        }
649
        else if (root.name() == KXMLQLCVCWidgetInput)
×
650
        {
651
            loadXMLInput(root);
×
652
        }
653
        else if (root.name() == KXMLQLCVCATKey)
×
654
        {
655
            setKeySequence(stripKeySequence(QKeySequence(root.readElementText())));
×
656
        }
657
        else if (root.name() == KXMLQLCVolumeBar)
×
658
        {
659
            m_volumeBar->loadXML(root, m_doc);
×
660
        }
661
        else if (root.name() == KXMLQLCSpectrumBar)
×
662
        {
663
            if (attrs.hasAttribute(KXMLQLCAudioBarIndex))
×
664
            {
665
                int idx = attrs.value(KXMLQLCAudioBarIndex).toString().toInt();
×
666
                if (idx >= 0 && idx < m_spectrumBars.count())
×
667
                    m_spectrumBars[idx]->loadXML(root, m_doc);
×
668
            }
669
        }
670
        else
671
        {
672
            qWarning() << Q_FUNC_INFO << "Unknown audio triggers tag:" << root.name().toString();
×
673
            root.skipCurrentElement();
×
674
        }
675
    }
×
676

677
    return true;
×
678
}
679

680
bool VCAudioTriggers::saveXML(QXmlStreamWriter *doc)
×
681
{
682
    Q_ASSERT(doc != NULL);
×
683

684
    /* VC button entry */
685
    doc->writeStartElement(KXMLQLCVCAudioTriggers);
×
686
    doc->writeAttribute(KXMLQLCVCATBarsNumber, QString::number(m_spectrumBars.count()));
×
687

688
    saveXMLCommon(doc);
×
689

690
    /* Window state */
691
    saveXMLWindowState(doc);
×
692

693
    /* Appearance */
694
    saveXMLAppearance(doc);
×
695

696
    /* Key sequence */
697
    if (m_keySequence.isEmpty() == false)
×
698
        doc->writeTextElement(KXMLQLCVCATKey, m_keySequence.toString());
×
699

700
    /* External input */
701
    saveXMLInput(doc);
×
702

703
    /* Lookup for any assigned bar */
704
    bool hasAssignment = false;
×
705
    if (m_volumeBar->m_type != AudioBar::None)
×
706
        hasAssignment = true;
×
707
    else
708
    {
709
        foreach (AudioBar *bar, m_spectrumBars)
×
710
        {
711
            if (bar->m_type != AudioBar::None)
×
712
            {
713
                hasAssignment = true;
×
714
                break;
×
715
            }
716
        }
×
717
    }
718

719
    if (hasAssignment == false)
×
720
    {
721
        /* End the <AudioTriggers> tag */
722
        doc->writeEndElement();
×
723
        return false;
×
724
    }
725

726
    if (m_volumeBar->m_type != AudioBar::None)
×
727
    {
728
        m_volumeBar->saveXML(doc, KXMLQLCVolumeBar, volumeBarIndex());
×
729
    }
730
    int idx = 0;
×
731
    foreach (AudioBar *bar, m_spectrumBars)
×
732
    {
733
        if (bar->m_type != AudioBar::None)
×
734
            bar->saveXML(doc, KXMLQLCSpectrumBar, idx);
×
735
        idx++;
×
736
    }
×
737

738
    /* End the <AudioTriggers> tag */
739
    doc->writeEndElement();
×
740

741
    return true;
×
742
}
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

© 2026 Coveralls, Inc