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

mcallegari / qlcplus / 8961243534

05 May 2024 09:23PM UTC coverage: 32.068% (+4.0%) from 28.094%
8961243534

push

github

mcallegari
Merge branch 'master' into qmltoqt6

902 of 2557 new or added lines in 140 files covered. (35.28%)

166 existing lines in 76 files now uncovered.

15395 of 48008 relevant lines covered (32.07%)

22949.67 hits per line

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

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

5
  Copyright (c) Heikki Junnila
6
                Massimo Callegari
7

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

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

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

21
#include <QXmlStreamReader>
22
#include <QXmlStreamWriter>
23
#include <QSettings>
24
#include <QLayout>
25
#include <QTimer>
26
#include <QDebug>
27

28
#include "vcspeeddialproperties.h"
29
#include "vcspeeddialfunction.h"
30
#include "vcpropertieseditor.h"
31
#include "vcspeeddialpreset.h"
32
#include "vcspeeddial.h"
33
#include "flowlayout.h"
34
#include "speeddial.h"
35
#include "qlcmacros.h"
36
#include "function.h"
37
#include "qlcfile.h"
38

39
#define UPDATE_TIMEOUT 50
40

41
const quint8 VCSpeedDial::absoluteInputSourceId = 0;
42
const quint8 VCSpeedDial::tapInputSourceId = 1;
43
const quint8 VCSpeedDial::multInputSourceId = 2;
44
const quint8 VCSpeedDial::divInputSourceId = 3;
45
const quint8 VCSpeedDial::multDivResetInputSourceId = 4;
46
const quint8 VCSpeedDial::applyInputSourceId = 5;
47
const QSize VCSpeedDial::defaultSize(QSize(200, 175));
48

49
static const QString presetBtnSS = "QPushButton { background-color: %1; height: 32px; border: 2px solid #6A6A6A; border-radius: 5px; }"
50
                                   "QPushButton:pressed { border: 2px solid #0000FF; }"
51
                                   "QPushButton:disabled { border: 2px solid #BBBBBB; color: #8f8f8f }";
52

53
/****************************************************************************
54
 * Initialization
55
 ****************************************************************************/
56

57
VCSpeedDial::VCSpeedDial(QWidget* parent, Doc* doc)
×
58
    : VCWidget(parent, doc)
59
    , m_currentFactor(1)
60
    , m_resetFactorOnDialChange(false)
61
    , m_absoluteValueMin(0)
62
    , m_absoluteValueMax(1000 * 10)
×
63
{
64
    setFrameStyle(KVCFrameStyleSunken);
×
65

66
    QVBoxLayout* vBox = new QVBoxLayout(this);
×
67
    vBox->setContentsMargins(0, 0, 0, 0);
×
68

69
    QHBoxLayout* speedDialHBox = new QHBoxLayout();
×
70
    vBox->addLayout(speedDialHBox);
×
71

72
    m_dial = new SpeedDial(this);
×
73
    speedDialHBox->addWidget(m_dial);
×
74
    connect(m_dial, SIGNAL(valueChanged(int)), this, SLOT(slotDialValueChanged()));
×
75
    connect(m_dial, SIGNAL(tapped()), this, SLOT(slotDialTapped()));
×
76
    connect(m_dial, SIGNAL(tapTimeout()), this, SLOT(slotTapTimeout()));
×
77

78
    m_factoredValue = m_dial->value();
×
79

80
    setType(VCWidget::SpeedDialWidget);
×
81
    setCaption(tr("Duration"));
×
82

83
    QSettings settings;
×
84
    QVariant var = settings.value(SETTINGS_SPEEDDIAL_SIZE);
×
85
    if (var.isValid() == true)
×
86
        resize(var.toSize());
×
87
    else
88
        resize(VCSpeedDial::defaultSize);
×
89

90
    var = settings.value(SETTINGS_SPEEDDIAL_VALUE);
×
91
    if (var.isValid() == true)
×
92
        m_dial->setValue(var.toUInt());
×
93

94
    // Multiplier, factor, divider and reset box
95
    QHBoxLayout* multFactorDivHBox = new QHBoxLayout();
×
96

97
    m_divButton = new QToolButton();
×
98
    m_divButton->setIconSize(QSize(32, 32));
×
99
    m_divButton->setIcon(QIcon(":/back.png"));
×
100
    m_divButton->setToolTip(tr("Divide the current time by 2"));
×
101
    connect(m_divButton, SIGNAL(clicked()),
×
102
            this, SLOT(slotDiv()));
103
    multFactorDivHBox->addWidget(m_divButton, Qt::AlignVCenter | Qt::AlignLeft);
×
104

105
    QVBoxLayout* labelsVboxBox = new QVBoxLayout();
×
106

107
    m_multDivLabel = new QLabel();
×
108
    m_multDivLabel->setAlignment(Qt::AlignCenter);
×
109
    m_multDivLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
×
110
    labelsVboxBox->addWidget(m_multDivLabel, Qt::AlignVCenter | Qt::AlignLeft);
×
111

112
    m_multDivResultLabel = new QLabel();
×
113
    m_multDivResultLabel->setAlignment(Qt::AlignCenter);
×
114
    m_multDivResultLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
×
115
    m_multDivResultLabel->setBackgroundRole(QPalette::BrightText);
×
116
    labelsVboxBox->addWidget(m_multDivResultLabel);
×
117

118
    multFactorDivHBox->addLayout(labelsVboxBox);
×
119

120
    m_multButton = new QToolButton();
×
121
    m_multButton->setIconSize(QSize(32, 32));
×
122
    m_multButton->setIcon(QIcon(":/forward.png"));
×
123
    m_multButton->setToolTip(tr("Multiply the current time by 2"));
×
124
    connect(m_multButton, SIGNAL(clicked()),
×
125
            this, SLOT(slotMult()));
126
    multFactorDivHBox->addWidget(m_multButton, Qt::AlignVCenter | Qt::AlignLeft);
×
127

128
    m_multDivResetButton = new QToolButton();
×
129
    m_multDivResetButton->setIconSize(QSize(32, 32));
×
130
    m_multDivResetButton->setIcon(QIcon(":/fileclose.png"));
×
131
    m_multDivResetButton->setToolTip(tr("Reset the current factor to 1x"));
×
132
    connect(m_multDivResetButton, SIGNAL(clicked()),
×
133
            this, SLOT(slotMultDivReset()));
134
    multFactorDivHBox->addWidget(m_multDivResetButton);
×
135

136
    vBox->addLayout(multFactorDivHBox);
×
137

138
    // Update labels
139
    slotMultDivChanged();
×
140

141
    // Apply button
142
    m_applyButton = new QPushButton();
×
143
    m_applyButton->setStyleSheet(presetBtnSS.arg("#DDDDDD"));
×
144
    m_applyButton->setText(tr("Apply"));
×
145
    m_applyButton->setToolTip(tr("Send the current value to the function now"));
×
146
    connect(m_applyButton, SIGNAL(clicked()),
×
147
            this, SLOT(slotFactoredValueChanged()));
148
    vBox->addWidget(m_applyButton);
×
149

150
    // Presets
151
    m_presetsLayout = new FlowLayout(3);
×
152
    vBox->addLayout(m_presetsLayout);
×
153

154
    // Don't show Infinite button: it's handled by presets
155
    setVisibilityMask(SpeedDial::defaultVisibilityMask() & ~SpeedDial::Infinite);
×
156

157
    /* Update timer */
158
    m_updateTimer = new QTimer(this);
×
159
    connect(m_updateTimer, SIGNAL(timeout()),
×
160
            this, SLOT(slotUpdate()));
161
    m_updateTimer->setSingleShot(true);
×
162

163
    slotModeChanged(m_doc->mode());
×
164
    setLiveEdit(m_liveEdit);
×
165
}
×
166

167
VCSpeedDial::~VCSpeedDial()
×
168
{
NEW
169
    foreach (VCSpeedDialPreset* preset, m_presets)
×
170
    {
171
        delete preset;
×
172
    }
173
}
×
174

175
void VCSpeedDial::enableWidgetUI(bool enable)
×
176
{
177
    m_dial->setEnabled(enable);
×
178

179
    // Mult and div
180
    m_multButton->setEnabled(enable);
×
181
    m_divButton->setEnabled(enable);
×
182
    m_multDivResetButton->setEnabled(enable);
×
183

184
    // Apply
185
    m_applyButton->setEnabled(enable);
×
186

187
    // Presets enable
188
    foreach (QWidget *presetWidget, m_presets.keys())
×
189
        presetWidget->setEnabled(enable);
×
190

191
    // Presets: update state
192
    if (enable)
×
193
        slotUpdate();
×
194
}
×
195

196
/*****************************************************************************
197
 * Clipboard
198
 *****************************************************************************/
199

200
VCWidget* VCSpeedDial::createCopy(VCWidget* parent)
×
201
{
202
    Q_ASSERT(parent != NULL);
×
203

204
    VCSpeedDial* dial = new VCSpeedDial(parent, m_doc);
×
205
    if (dial->copyFrom(this) == false)
×
206
    {
207
        delete dial;
×
208
        dial = NULL;
×
209
    }
210

211
    return dial;
×
212
}
213

214
bool VCSpeedDial::copyFrom(const VCWidget* widget)
×
215
{
216
    const VCSpeedDial* dial = qobject_cast<const VCSpeedDial*> (widget);
×
217
    if (dial == NULL)
×
218
        return false;
×
219

220
    setFunctions(dial->functions());
×
221
    setAbsoluteValueRange(dial->absoluteValueMin(), dial->absoluteValueMax());
×
222
    setVisibilityMask(dial->visibilityMask());
×
223
    setResetFactorOnDialChange(dial->resetFactorOnDialChange());
×
224

225
    setTapKeySequence(dial->tapKeySequence());
×
226
    setMultKeySequence(dial->multKeySequence());
×
227
    setDivKeySequence(dial->divKeySequence());
×
228
    setMultDivResetKeySequence(dial->multDivResetKeySequence());
×
229
    setApplyKeySequence(dial->applyKeySequence());
×
230

231
    resetPresets();
×
232
    foreach (VCSpeedDialPreset const* preset, dial->presets())
×
233
    {
234
        addPreset(*preset);
×
235
    }
236

237
    /* Copy common stuff */
238
    return VCWidget::copyFrom(widget);
×
239
}
240

241
/*****************************************************************************
242
 * Properties
243
 *****************************************************************************/
244

245
void VCSpeedDial::editProperties()
×
246
{
247
    VCSpeedDialProperties sdp(this, m_doc);
×
248
    sdp.exec();
×
249
}
×
250

251
/*****************************************************************************
252
 * Caption
253
 *****************************************************************************/
254

255
void VCSpeedDial::setCaption(const QString& text)
×
256
{
257
    VCWidget::setCaption(text);
×
258

259
    Q_ASSERT(m_dial != NULL);
×
260
    m_dial->setTitle(text);
×
261
}
×
262

263
/*****************************************************************************
264
 * QLC Mode
265
 *****************************************************************************/
266

267
void VCSpeedDial::slotModeChanged(Doc::Mode mode)
×
268
{
269
    if (mode == Doc::Operate && isDisabled() == false)
×
270
    {
271
        enableWidgetUI(true);
×
272
        updateFeedback();
×
273
    }
274
    else
275
    {
276
        m_dial->stopTimers();
×
277
        enableWidgetUI(false);
×
278
    }
279
    VCWidget::slotModeChanged(mode);
×
280
}
×
281

282
/****************************************************************************
283
 * Functions
284
 ****************************************************************************/
285

286
void VCSpeedDial::setFunctions(const QList <VCSpeedDialFunction> & functions)
×
287
{
288
    m_functions = functions;
×
289
}
×
290

291
QList <VCSpeedDialFunction> VCSpeedDial::functions() const
×
292
{
293
    return m_functions;
×
294
}
295

296
void VCSpeedDial::tap()
×
297
{
298
    m_dial->tap();
×
299
}
×
300

301
void VCSpeedDial::slotDialValueChanged()
×
302
{
303
    // The (m_currentFactor != 1) test ensures that we don't call
304
    // slotMultDivChanged() 2 times
305
    if (m_resetFactorOnDialChange && m_currentFactor != 1)
×
306
        slotMultDivReset();
×
307
    else
308
        slotMultDivChanged();
×
309

310
    m_updateTimer->start(UPDATE_TIMEOUT);
×
311
}
×
312

313
void VCSpeedDial::slotDialTapped()
×
314
{
315
    foreach (const VCSpeedDialFunction &speeddialfunction, m_functions)
×
316
    {
317
        Function* function = m_doc->function(speeddialfunction.functionId);
×
318
        if (function != NULL)
×
319
        {
320
            if (speeddialfunction.durationMultiplier != VCSpeedDialFunction::None)
×
321
                function->tap();
×
322
        }
323
    }
324
}
×
325

326
void VCSpeedDial::slotTapTimeout()
×
327
{
328
    updateFeedback();
×
329
}
×
330

331
void VCSpeedDial::slotUpdate()
×
332
{
333
    int currentValue = m_dial->value();
×
334

335
    for (QHash<QWidget*, VCSpeedDialPreset*>::iterator it = m_presets.begin();
×
336
            it != m_presets.end(); ++it)
×
337
    {
338
        QWidget* widget = it.key();
×
339
        VCSpeedDialPreset* preset = it.value();
×
340

341
        QPushButton* button = reinterpret_cast<QPushButton*>(widget);
×
342
        button->setDown(preset->m_value == currentValue);
×
343
    }
344
    updateFeedback();
×
345
}
×
346

347
/*********************************************************************
348
 * Presets
349
 *********************************************************************/
350

351
void VCSpeedDial::addPreset(VCSpeedDialPreset const& preset)
×
352
{
353
    QWidget *presetWidget = NULL;
×
354

355
    {
356
        QPushButton *presetButton = new QPushButton(this);
×
357
        presetWidget = presetButton;
×
358
        presetButton->setStyleSheet(presetBtnSS.arg("#BBBBBB"));
×
359
        presetButton->setMinimumWidth(36);
×
360
        presetButton->setMaximumWidth(80);
×
361
        presetButton->setFocusPolicy(Qt::TabFocus);
×
362
        QString btnLabel = preset.m_name;
×
363
        presetButton->setToolTip(btnLabel);
×
364
        presetButton->setText(fontMetrics().elidedText(btnLabel, Qt::ElideRight, 72));
×
365
    }
366

367
    Q_ASSERT(presetWidget != NULL);
×
368

369
    connect(reinterpret_cast<QPushButton*>(presetWidget), SIGNAL(clicked()),
×
370
            this, SLOT(slotPresetClicked()));
371

372
    if (mode() == Doc::Design)
×
373
        presetWidget->setEnabled(false);
×
374

375
    m_presets[presetWidget] = new VCSpeedDialPreset(preset);
×
376
    m_presetsLayout->addWidget(presetWidget);
×
377

378
    if (m_presets[presetWidget]->m_inputSource != NULL)
×
379
    {
380
        setInputSource(m_presets[presetWidget]->m_inputSource,
×
381
                       m_presets[presetWidget]->m_id);
×
382
    }
383

384
    m_updateTimer->start(UPDATE_TIMEOUT);
×
385
}
×
386

387
void VCSpeedDial::resetPresets()
×
388
{
389
    for (QHash<QWidget*, VCSpeedDialPreset*>::iterator it = m_presets.begin();
×
390
            it != m_presets.end(); ++it)
×
391
    {
392
        QWidget* widget = it.key();
×
393
        m_presetsLayout->removeWidget(widget);
×
394
        delete widget;
×
395

396
        VCSpeedDialPreset* preset = it.value();
×
397
        if (!preset->m_inputSource.isNull())
×
398
            setInputSource(QSharedPointer<QLCInputSource>(), preset->m_id);
×
399
        delete preset;
×
400
    }
401
    m_presets.clear();
×
402
}
×
403

404
QList<VCSpeedDialPreset*> VCSpeedDial::presets() const
×
405
{
406
    QList<VCSpeedDialPreset*> presetsList = m_presets.values();
×
407
    std::sort(presetsList.begin(), presetsList.end(), VCSpeedDialPreset::compare);
×
408
    return presetsList;
×
409
}
410

411
void VCSpeedDial::slotPresetClicked()
×
412
{
413
    QPushButton *btn = qobject_cast<QPushButton*>(sender());
×
414
    VCSpeedDialPreset *preset = m_presets[btn];
×
415

416
    Q_ASSERT(preset != NULL);
×
417

418
    {
419
        // Special case: infinite buttons should act as checkboxes
420
        // so the previous value can be restore when clicking 2 times on them
421
        if (preset->m_value == (int)Function::infiniteSpeed())
×
422
        {
423
            m_dial->toggleInfinite();
×
424
        }
425
        else // Normal case
426
        {
427
            m_dial->setValue(preset->m_value, true);
×
428
        }
429
    }
430
}
×
431

432
void VCSpeedDial::slotMult()
×
433
{
434
    if (m_currentFactor == -2)
×
435
    {
436
        m_currentFactor = 1;
×
437
        slotMultDivChanged();
×
438
    }
439
    else if (m_currentFactor > 0)
×
440
    {
441
        if (m_currentFactor < 2048)
×
442
        {
443
            m_currentFactor *= 2;
×
444
            slotMultDivChanged();
×
445
        }
446
    }
447
    else
448
    {
449
        m_currentFactor /= 2;
×
450
        slotMultDivChanged();
×
451
    }
452
}
×
453

454
void VCSpeedDial::slotDiv()
×
455
{
456
    if (m_currentFactor == 1)
×
457
    {
458
        m_currentFactor = -2;
×
459
        slotMultDivChanged();
×
460
    }
461
    else if (m_currentFactor > 0)
×
462
    {
463
        m_currentFactor /= 2;
×
464
        slotMultDivChanged();
×
465
    }
466
    else
467
    {
468
        if (m_currentFactor > -2048)
×
469
        {
470
            m_currentFactor *= 2;
×
471
            slotMultDivChanged();
×
472
        }
473
    }
474
}
×
475

476
void VCSpeedDial::slotMultDivReset()
×
477
{
478
    if (m_currentFactor != 1)
×
479
    {
480
        m_currentFactor = 1;
×
481
        slotMultDivChanged();
×
482
    }
483
}
×
484

485
void VCSpeedDial::slotMultDivChanged()
×
486
{
487
    if (m_currentFactor > 0)
×
488
    {
489
        m_factoredValue = m_dial->value() * m_currentFactor;
×
490
        m_multDivLabel->setText(QString("%1x").arg(m_currentFactor));
×
491
    }
492
    else
493
    {
494
        m_factoredValue = m_dial->value() / qAbs(m_currentFactor);
×
495
        m_multDivLabel->setText(QString("1/%1x").arg(qAbs(m_currentFactor)));
×
496
    }
497
    m_multDivResultLabel->setText("(" + Function::speedToString(m_factoredValue) + ")");
×
498

499
    slotFactoredValueChanged();
×
500
}
×
501

502
void VCSpeedDial::slotFactoredValueChanged()
×
503
{
504
    const QVector<quint32> multipliers = VCSpeedDialFunction::speedMultiplierValuesTimes1000();
×
505

506
    int ms = m_factoredValue;
×
507

508
    foreach (const VCSpeedDialFunction &speeddialfunction, m_functions)
×
509
    {
510
        Function* function = m_doc->function(speeddialfunction.functionId);
×
511
        if (function != NULL)
×
512
        {
513
            if (speeddialfunction.fadeInMultiplier != VCSpeedDialFunction::None)
×
514
            {
515
                if ((uint)ms != Function::infiniteSpeed())
×
516
                    function->setFadeInSpeed(ms * ((float)multipliers[speeddialfunction.fadeInMultiplier] / 1000.0));
×
517
                else
518
                    function->setFadeInSpeed(ms);
×
519
            }
520
            if (speeddialfunction.fadeOutMultiplier != VCSpeedDialFunction::None)
×
521
            {
522
                if ((uint)ms != Function::infiniteSpeed())
×
523
                    function->setFadeOutSpeed(ms * ((float)multipliers[speeddialfunction.fadeOutMultiplier] / 1000.0));
×
524
                else
525
                    function->setFadeOutSpeed(ms);
×
526
            }
527
            if (speeddialfunction.durationMultiplier != VCSpeedDialFunction::None)
×
528
            {
529
                if ((uint)ms != Function::infiniteSpeed())
×
530
                    function->setDuration(ms * ((float)multipliers[speeddialfunction.durationMultiplier] / 1000.0));
×
531
                else
532
                    function->setDuration(ms);
×
533
            }
534
        }
535
    }
536
}
×
537

538

539
void VCSpeedDial::setResetFactorOnDialChange(bool value)
×
540
{
541
    m_resetFactorOnDialChange = value;
×
542
}
×
543

544
bool VCSpeedDial::resetFactorOnDialChange() const
×
545
{
546
    return m_resetFactorOnDialChange;
×
547
}
548

549
/*****************************************************************************
550
 * External input
551
 *****************************************************************************/
552

553
void VCSpeedDial::updateFeedback()
×
554
{
555
    // Feedback to absolute input source
556
    int fbv = (int)SCALE(float(m_dial->value()), float(m_absoluteValueMin),
×
557
                     float(m_absoluteValueMax), float(0), float(UCHAR_MAX));
558

559
    sendFeedback(fbv, absoluteInputSourceId);
×
560

561
    // Feedback to tap button
562
    sendFeedback(m_dial->isTapTick() ? 255 : 0, tapInputSourceId);
×
563

564
    // Feedback to preset buttons
565
    for (QHash<QWidget*, VCSpeedDialPreset*>::iterator it = m_presets.begin();
×
566
            it != m_presets.end(); ++it)
×
567
    {
568
        VCSpeedDialPreset* preset = it.value();
×
569
        if (preset->m_inputSource != NULL)
×
570
        {
571
            QPushButton* button = reinterpret_cast<QPushButton*>(it.key());
×
572
            if (preset->m_inputSource.isNull() == false)
×
573
                sendFeedback(button->isDown() ?
×
NEW
574
                             preset->m_inputSource->feedbackValue(QLCInputFeedback::UpperValue) :
×
NEW
575
                             preset->m_inputSource->feedbackValue(QLCInputFeedback::LowerValue),
×
UNCOV
576
                             preset->m_inputSource);
×
577
        }
578
    }
579
}
×
580

581
void VCSpeedDial::slotInputValueChanged(quint32 universe, quint32 channel, uchar value)
×
582
{
583
    /* Don't let input data through in design mode or if disabled */
584
    if (acceptsInput() == false)
×
585
        return;
×
586

587
    quint32 pagedCh = (page() << 16) | channel;
×
588

589
    if (checkInputSource(universe, pagedCh, value, sender(), tapInputSourceId))
×
590
    {
591
        if (value != 0)
×
592
            m_dial->tap();
×
593
    }
594
    else if (checkInputSource(universe, pagedCh, value, sender(), absoluteInputSourceId))
×
595
    {
596
        int ms = static_cast<int> (SCALE(qreal(value), qreal(0), qreal(255),
×
597
                                         qreal(absoluteValueMin()),
598
                                         qreal(absoluteValueMax())));
×
599
        m_dial->setValue(ms, true);
×
600
    }
601
    else if (checkInputSource(universe, pagedCh, value, sender(), multInputSourceId))
×
602
    {
603
        if (value != 0)
×
604
            slotMult();
×
605
    }
606
    else if (checkInputSource(universe, pagedCh, value, sender(), divInputSourceId))
×
607
    {
608
        if (value != 0)
×
609
            slotDiv();
×
610
    }
611
    else if (checkInputSource(universe, pagedCh, value, sender(), multDivResetInputSourceId))
×
612
    {
613
        if (value != 0)
×
614
            slotMultDivReset();
×
615
    }
616
    else if (checkInputSource(universe, pagedCh, value, sender(), applyInputSourceId))
×
617
    {
618
        if (value != 0)
×
619
            slotFactoredValueChanged();
×
620
    }
621
    else
622
    {
623
        for (QHash<QWidget*, VCSpeedDialPreset*>::iterator it = m_presets.begin();
×
624
                it != m_presets.end(); ++it)
×
625
        {
626
            VCSpeedDialPreset *preset = it.value();
×
627
            if (preset->m_inputSource != NULL &&
×
628
                    preset->m_inputSource->universe() == universe &&
×
629
                    preset->m_inputSource->channel() == pagedCh)
×
630
            {
631
                {
632
                    QPushButton *button = reinterpret_cast<QPushButton*>(it.key());
×
633
                    button->click();
×
634
                }
635
            }
636
        }
637
    }
638
}
639

640
/*********************************************************************
641
 * Tap key sequence handler
642
 *********************************************************************/
643

644
void VCSpeedDial::setTapKeySequence(const QKeySequence& keySequence)
×
645
{
646
    m_tapKeySequence = QKeySequence(keySequence);
×
647
}
×
648

649
QKeySequence VCSpeedDial::tapKeySequence() const
×
650
{
651
    return m_tapKeySequence;
×
652
}
653

654
void VCSpeedDial::setMultKeySequence(const QKeySequence& keySequence)
×
655
{
656
    m_multKeySequence = QKeySequence(keySequence);
×
657
}
×
658

659
QKeySequence VCSpeedDial::multKeySequence() const
×
660
{
661
    return m_multKeySequence;
×
662
}
663

664
void VCSpeedDial::setDivKeySequence(const QKeySequence& keySequence)
×
665
{
666
    m_divKeySequence = QKeySequence(keySequence);
×
667
}
×
668

669
QKeySequence VCSpeedDial::divKeySequence() const
×
670
{
671
    return m_divKeySequence;
×
672
}
673

674
void VCSpeedDial::setMultDivResetKeySequence(const QKeySequence& keySequence)
×
675
{
676
    m_multDivResetKeySequence = QKeySequence(keySequence);
×
677
}
×
678

679
QKeySequence VCSpeedDial::multDivResetKeySequence() const
×
680
{
681
    return m_multDivResetKeySequence;
×
682
}
683

684
void VCSpeedDial::setApplyKeySequence(const QKeySequence& keySequence)
×
685
{
686
    m_applyKeySequence = QKeySequence(keySequence);
×
687
}
×
688

689
QKeySequence VCSpeedDial::applyKeySequence() const
×
690
{
691
    return m_applyKeySequence;
×
692
}
693

694
void VCSpeedDial::slotKeyPressed(const QKeySequence& keySequence)
×
695
{
696
    if (acceptsInput() == false)
×
697
        return;
×
698

699
    if (m_tapKeySequence == keySequence)
×
700
        m_dial->tap();
×
701

702
    if (m_multKeySequence == keySequence)
×
703
        slotMult();
×
704
    if (m_divKeySequence == keySequence)
×
705
        slotDiv();
×
706
    if (m_multDivResetKeySequence == keySequence)
×
707
        slotMultDivReset();
×
708
    if (m_applyKeySequence == keySequence)
×
709
        slotFactoredValueChanged();
×
710

711
    for (QHash<QWidget*, VCSpeedDialPreset*>::iterator it = m_presets.begin();
×
712
            it != m_presets.end(); ++it)
×
713
    {
714
        VCSpeedDialPreset *preset = it.value();
×
715
        if (preset->m_keySequence == keySequence)
×
716
        {
717
            QPushButton *button = reinterpret_cast<QPushButton*>(it.key());
×
718
            button->click();
×
719
        }
720
    }
721
}
722

723

724
/****************************************************************************
725
 * Absolute value range
726
 ****************************************************************************/
727

728
void VCSpeedDial::setAbsoluteValueRange(uint min, uint max)
×
729
{
730
    m_absoluteValueMin = min;
×
731
    m_absoluteValueMax = max;
×
732
}
×
733

734
uint VCSpeedDial::absoluteValueMin() const
×
735
{
736
    return m_absoluteValueMin;
×
737
}
738

739
uint VCSpeedDial::absoluteValueMax() const
×
740
{
741
    return m_absoluteValueMax;
×
742
}
743

744
quint32 VCSpeedDial::visibilityMask() const
×
745
{
746
    return m_visibilityMask;
×
747
}
748

749
void VCSpeedDial::setVisibilityMask(quint32 mask)
×
750
{
751
    if (m_dial != NULL)
×
752
        m_dial->setVisibilityMask(mask);
×
753

754
    if (mask & MultDiv)
×
755
    {
756
        m_multButton->show();
×
757
        m_multDivLabel->show();
×
758
        m_divButton->show();
×
759
        m_multDivResetButton->show();
×
760
        m_multDivResultLabel->show();
×
761
    }
762
    else
763
    {
764
        m_multButton->hide();
×
765
        m_multDivLabel->hide();
×
766
        m_divButton->hide();
×
767
        m_multDivResetButton->hide();
×
768
        m_multDivResultLabel->hide();
×
769
    }
770

771
    if (mask & Apply)
×
772
        m_applyButton->show();
×
773
    else
774
        m_applyButton->hide();
×
775

776
    m_visibilityMask = mask;
×
777
}
×
778

779
/*****************************************************************************
780
 * Load & Save
781
 *****************************************************************************/
782

783
static QSharedPointer<VCSpeedDialPreset> createInfinitePreset()
×
784
{
785
    QSharedPointer<VCSpeedDialPreset> infinitePreset(new VCSpeedDialPreset(16));
×
786
    infinitePreset->m_value = Function::infiniteSpeed();
×
787
    infinitePreset->m_name = Function::speedToString(Function::infiniteSpeed());
×
788
    return infinitePreset;
×
789
}
790

791
bool VCSpeedDial::loadXML(QXmlStreamReader &root)
×
792
{
793
    if (root.name() != KXMLQLCVCSpeedDial)
×
794
    {
795
        qWarning() << Q_FUNC_INFO << "SpeedDial node not found";
×
796
        return false;
×
797
    }
798

799
    /* Widget commons */
800
    loadXMLCommon(root);
×
801

802
    // Compatibility with old workspace files:
803
    // Get old style speedtype selection
804
    VCSpeedDialFunction::SpeedMultiplier defaultFadeInMultiplier = VCSpeedDialFunction::None;
×
805
    VCSpeedDialFunction::SpeedMultiplier defaultFadeOutMultiplier = VCSpeedDialFunction::None;
×
806
    VCSpeedDialFunction::SpeedMultiplier defaultDurationMultiplier = VCSpeedDialFunction::One;
×
807
    if (root.attributes().hasAttribute(KXMLQLCVCSpeedDialSpeedTypes))
×
808
    {
809
        SpeedTypes speedTypes = SpeedTypes(root.attributes().value(KXMLQLCVCSpeedDialSpeedTypes).toString().toInt());
×
810
        defaultFadeInMultiplier = (speedTypes & FadeIn) ? VCSpeedDialFunction::One : VCSpeedDialFunction::None;
×
811
        defaultFadeOutMultiplier = (speedTypes & FadeOut) ? VCSpeedDialFunction::One : VCSpeedDialFunction::None;
×
812
        defaultDurationMultiplier = (speedTypes & Duration) ? VCSpeedDialFunction::One : VCSpeedDialFunction::None;
×
813
    }
814

815
    // Sorted list for new presets
816
    QList<VCSpeedDialPreset> newPresets;
×
817
    // legacy: transform the infinite checkbox into an infinite preset
818
    QSharedPointer<VCSpeedDialPreset> infinitePreset(NULL);
×
819

820
    /* Children */
821
    while (root.readNextStartElement())
×
822
    {
823
        //qDebug() << "VC Speed Dial tag:" << root.name();
824
        if (root.name() == KXMLQLCFunction)
×
825
        {
826
            // Function
827
            VCSpeedDialFunction speeddialfunction;
×
828
            if (speeddialfunction.loadXML(root, defaultFadeInMultiplier,
×
829
                                          defaultFadeOutMultiplier,
830
                                          defaultDurationMultiplier))
831
            {
832
                m_functions.append(speeddialfunction);
×
833
            }
834
        }
835
        else if (root.name() == KXMLQLCWindowState)
×
836
        {
837
            int x = 0, y = 0, w = 0, h = 0;
×
838
            bool visible = true;
×
839
            loadXMLWindowState(root, &x, &y, &w, &h, &visible);
×
840
            setGeometry(x, y, w, h);
×
841
        }
842
        else if (root.name() == KXMLQLCVCWidgetAppearance)
×
843
        {
844
            loadXMLAppearance(root);
×
845
        }
846
        else if (root.name() == KXMLQLCVCSpeedDialAbsoluteValue)
×
847
        {
848
            // Value range
849
            QXmlStreamAttributes vAttrs = root.attributes();
×
850
            if (vAttrs.hasAttribute(KXMLQLCVCSpeedDialAbsoluteValueMin) &&
×
851
                vAttrs.hasAttribute(KXMLQLCVCSpeedDialAbsoluteValueMax))
×
852
            {
853
                uint min = vAttrs.value(KXMLQLCVCSpeedDialAbsoluteValueMin).toString().toUInt();
×
854
                uint max = vAttrs.value(KXMLQLCVCSpeedDialAbsoluteValueMax).toString().toUInt();
×
855
                setAbsoluteValueRange(min, max);
×
856
            }
857
            loadXMLSources(root, absoluteInputSourceId);
×
858
        }
859
        else if (root.name() == KXMLQLCVCSpeedDialTap)
×
860
        {
861
            loadXMLSources(root, tapInputSourceId);
×
862
        }
863
        else if (root.name() == KXMLQLCVCSpeedDialResetFactorOnDialChange)
×
864
        {
865
            // Reset factor on dial change
866
            setResetFactorOnDialChange(root.readElementText() == KXMLQLCTrue);
×
867
        }
868
        else if (root.name() == KXMLQLCVCSpeedDialMult)
×
869
        {
870
            loadXMLSources(root, multInputSourceId);
×
871
        }
872
        else if (root.name() == KXMLQLCVCSpeedDialDiv)
×
873
        {
874
            loadXMLSources(root, divInputSourceId);
×
875
        }
876
        else if (root.name() == KXMLQLCVCSpeedDialMultDivReset)
×
877
        {
878
            loadXMLSources(root, multDivResetInputSourceId);
×
879
        }
880
        else if (root.name() == KXMLQLCVCSpeedDialApply)
×
881
        {
882
            loadXMLSources(root, applyInputSourceId);
×
883
        }
884
        else if (root.name() == KXMLQLCVCSpeedDialTapKey)
×
885
        {
886
            setTapKeySequence(stripKeySequence(QKeySequence(root.readElementText())));
×
887
        }
888
        else if (root.name() == KXMLQLCVCSpeedDialMultKey)
×
889
        {
890
            setMultKeySequence(stripKeySequence(QKeySequence(root.readElementText())));
×
891
        }
892
        else if (root.name() == KXMLQLCVCSpeedDialDivKey)
×
893
        {
894
            setDivKeySequence(stripKeySequence(QKeySequence(root.readElementText())));
×
895
        }
896
        else if (root.name() == KXMLQLCVCSpeedDialMultDivResetKey)
×
897
        {
898
            setMultDivResetKeySequence(stripKeySequence(QKeySequence(root.readElementText())));
×
899
        }
900
        else if (root.name() == KXMLQLCVCSpeedDialApplyKey)
×
901
        {
902
            setApplyKeySequence(stripKeySequence(QKeySequence(root.readElementText())));
×
903
        }
904
        else if (root.name() == KXMLQLCVCSpeedDialInfinite)
×
905
        {
906
            // Legacy: infinite checkbox input
907
            if (!infinitePreset)
×
908
                infinitePreset = createInfinitePreset();
×
909

910
            loadXMLInfiniteLegacy(root, infinitePreset);
×
911
        }
912
        else if (root.name() == KXMLQLCVCSpeedDialInfiniteKey)
×
913
        {
914
            // Legacy: infinite checkbox key sequence
915
            if (!infinitePreset)
×
916
                infinitePreset = createInfinitePreset();
×
917

918
            infinitePreset->m_keySequence = stripKeySequence(QKeySequence(root.readElementText()));
×
919
        }
NEW
920
        else if (root.name() == KXMLQLCVCSpeedDialPreset)
×
921
        {
922
            VCSpeedDialPreset preset(0xff);
×
923
            if (preset.loadXML(root))
×
924
                newPresets.insert(std::lower_bound(newPresets.begin(), newPresets.end(), preset), preset);
×
925
        }
926
        else if (root.name() == KXMLQLCVCSpeedDialVisibilityMask)
×
927
        {
928
            quint32 mask = root.readElementText().toUInt();
×
929

930
            // legacy: infinite checkbox
931
            if (mask & SpeedDial::Infinite)
×
932
            {
933
                mask &= ~SpeedDial::Infinite;
×
934
                if (!infinitePreset)
×
935
                    infinitePreset = createInfinitePreset();
×
936
            }
937

938
            setVisibilityMask(mask);
×
939
        }
940
        else if (root.name() == KXMLQLCVCSpeedDialTime)
×
941
        {
942
            m_dial->setValue(root.readElementText().toUInt());
×
943
        }
944
        else
945
        {
946
            qWarning() << Q_FUNC_INFO << "Unknown speed dial tag:" << root.name().toString();
×
947
            root.skipCurrentElement();
×
948
        }
949
    }
950

951
    if (infinitePreset && newPresets.size() > 0)
×
952
    {
953
        qWarning() << Q_FUNC_INFO << "Can't have an infinite checkbox + presets";
×
954
        return false;
×
955
    }
956

957
    if (infinitePreset)
×
958
        addPreset(*infinitePreset);
×
959
    else
960
    {
961
        foreach (VCSpeedDialPreset const& preset, newPresets)
×
962
            addPreset(preset);
×
963
    }
964

965
    return true;
×
966
}
967

968
bool VCSpeedDial::loadXMLInfiniteLegacy(QXmlStreamReader &root, QSharedPointer<VCSpeedDialPreset> preset)
×
969
{
970
    while (root.readNextStartElement())
×
971
    {
972
        if (root.name() == KXMLQLCVCWidgetInput)
×
973
        {
974
            quint32 uni = QLCInputSource::invalidUniverse;
×
975
            quint32 ch = QLCInputSource::invalidChannel;
×
976
            if (loadXMLInput(root, &uni, &ch) == true)
×
977
            {
978
                preset->m_inputSource = QSharedPointer<QLCInputSource>(new QLCInputSource(uni, ch));
×
979
            }
980
        }
981
        else
982
        {
983
            qWarning() << Q_FUNC_INFO << "Unknown Frame Source tag" << root.name().toString();
×
984
            root.skipCurrentElement();
×
985
        }
986
    }
987
    return true;
×
988
}
989

990
bool VCSpeedDial::saveXML(QXmlStreamWriter *doc)
×
991
{
992
    Q_ASSERT(doc != NULL);
×
993

994
    doc->writeStartElement(KXMLQLCVCSpeedDial);
×
995

996
    saveXMLCommon(doc);
×
997

998
    /* Window state */
999
    saveXMLWindowState(doc);
×
1000

1001
    /* Appearance */
1002
    saveXMLAppearance(doc);
×
1003

1004
    if (m_visibilityMask != SpeedDial::defaultVisibilityMask())
×
1005
    {
1006
        doc->writeTextElement(KXMLQLCVCSpeedDialVisibilityMask, QString::number(m_visibilityMask));
×
1007
    }
1008

1009
    /* Absolute input */
1010
    doc->writeStartElement(KXMLQLCVCSpeedDialAbsoluteValue);
×
1011
    doc->writeAttribute(KXMLQLCVCSpeedDialAbsoluteValueMin, QString::number(absoluteValueMin()));
×
1012
    doc->writeAttribute(KXMLQLCVCSpeedDialAbsoluteValueMax, QString::number(absoluteValueMax()));
×
1013
    saveXMLInput(doc, inputSource(absoluteInputSourceId));
×
1014
    doc->writeEndElement();
×
1015

1016
    /* Tap input */
1017
    QSharedPointer<QLCInputSource> tapSrc = inputSource(tapInputSourceId);
×
1018
    if (!tapSrc.isNull() && tapSrc->isValid())
×
1019
    {
1020
        doc->writeStartElement(KXMLQLCVCSpeedDialTap);
×
1021
        saveXMLInput(doc, tapSrc);
×
1022
        doc->writeEndElement();
×
1023
    }
1024

1025
    // MultDiv options
1026
    if (m_resetFactorOnDialChange)
×
1027
        doc->writeTextElement(KXMLQLCVCSpeedDialResetFactorOnDialChange, KXMLQLCTrue);
×
1028

1029
    /* Mult input */
1030
    QSharedPointer<QLCInputSource> multSrc = inputSource(multInputSourceId);
×
1031
    if (!multSrc.isNull() && multSrc->isValid())
×
1032
    {
1033
        doc->writeStartElement(KXMLQLCVCSpeedDialMult);
×
1034
        saveXMLInput(doc, multSrc);
×
1035
        doc->writeEndElement();
×
1036
    }
1037

1038
    /* Div input */
1039
    QSharedPointer<QLCInputSource> divSrc = inputSource(divInputSourceId);
×
1040
    if (!divSrc.isNull() && divSrc->isValid())
×
1041
    {
1042
        doc->writeStartElement(KXMLQLCVCSpeedDialDiv);
×
1043
        saveXMLInput(doc, divSrc);
×
1044
        doc->writeEndElement();
×
1045
    }
1046

1047
    /* MultDiv Reset input */
1048
    QSharedPointer<QLCInputSource> resetSrc = inputSource(multDivResetInputSourceId);
×
1049
    if (!resetSrc.isNull() && resetSrc->isValid())
×
1050
    {
1051
        doc->writeStartElement(KXMLQLCVCSpeedDialMultDivReset);
×
1052
        saveXMLInput(doc, resetSrc);
×
1053
        doc->writeEndElement();
×
1054
    }
1055

1056
    /* Apply input */
1057
    QSharedPointer<QLCInputSource> applySrc = inputSource(applyInputSourceId);
×
1058
    if (!applySrc.isNull() && applySrc->isValid())
×
1059
    {
1060
        doc->writeStartElement(KXMLQLCVCSpeedDialApply);
×
1061
        saveXMLInput(doc, applySrc);
×
1062
        doc->writeEndElement();
×
1063
    }
1064

1065
    /* Save time */
1066
    doc->writeTextElement(KXMLQLCVCSpeedDialTime, QString::number(m_dial->value()));
×
1067

1068
    /* Tap key sequence */
1069
    if (m_tapKeySequence.isEmpty() == false)
×
1070
        doc->writeTextElement(KXMLQLCVCSpeedDialTapKey, m_tapKeySequence.toString());
×
1071

1072
    /* Mult key sequence */
1073
    if (m_multKeySequence.isEmpty() == false)
×
1074
        doc->writeTextElement(KXMLQLCVCSpeedDialMultKey, m_multKeySequence.toString());
×
1075

1076
    /* Div key sequence */
1077
    if (m_divKeySequence.isEmpty() == false)
×
1078
        doc->writeTextElement(KXMLQLCVCSpeedDialDivKey, m_divKeySequence.toString());
×
1079

1080
    /* MultDiv Reset key sequence */
1081
    if (m_multDivResetKeySequence.isEmpty() == false)
×
1082
        doc->writeTextElement(KXMLQLCVCSpeedDialMultDivResetKey, m_multDivResetKeySequence.toString());
×
1083

1084
    /* MultDiv Reset key sequence */
1085
    if (m_applyKeySequence.isEmpty() == false)
×
1086
        doc->writeTextElement(KXMLQLCVCSpeedDialApplyKey, m_applyKeySequence.toString());
×
1087

1088
    /* Functions */
1089
    foreach (const VCSpeedDialFunction &speeddialfunction, m_functions)
×
1090
        speeddialfunction.saveXML(doc);
×
1091

1092
    // Presets
NEW
1093
    foreach (VCSpeedDialPreset *preset, presets())
×
1094
        preset->saveXML(doc);
×
1095

1096
    /* End the <SpeedDial> tag */
1097
    doc->writeEndElement();
×
1098

1099
    return true;
×
1100
}
1101

1102
void VCSpeedDial::postLoad()
×
1103
{
1104
    /* Remove such function IDs that don't exist */
1105
    QMutableListIterator <VCSpeedDialFunction> it(m_functions);
×
1106
    while (it.hasNext() == true)
×
1107
    {
1108
        it.next();
×
1109
        Function* function = m_doc->function(it.value().functionId);
×
1110
        if (function == NULL)
×
1111
            it.remove();
×
1112
    }
UNCOV
1113
}
×
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