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

mcallegari / qlcplus / 10668847825

02 Sep 2024 02:18PM UTC coverage: 31.426% (-0.07%) from 31.498%
10668847825

push

github

web-flow
Merge pull request #1610 from Ledjlale/fix/qt6_rebase2

qmltoqt6 rebasing

25 of 290 new or added lines in 19 files covered. (8.62%)

25 existing lines in 11 files now uncovered.

15012 of 47769 relevant lines covered (31.43%)

19745.74 hits per line

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

15.98
/ui/src/virtualconsole/vcslider.cpp
1
/*
2
  Q Light Controller Plus
3
  vcslider.cpp
4

5
  Copyright (c) Heikki Junnila
6
                Stefan Krumm
7
                Massimo Callegari
8

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

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

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

22
#include <QXmlStreamReader>
23
#include <QXmlStreamWriter>
24
#include <QWidgetAction>
25
#include <QVBoxLayout>
26
#include <QHBoxLayout>
27
#include <QMessageBox>
28
#include <QPaintEvent>
29
#include <QSettings>
30
#include <QPainter>
31
#include <QString>
32
#include <QSlider>
33
#include <QTimer>
34
#include <QDebug>
35
#include <QLabel>
36
#include <math.h>
37
#include <QMenu>
38
#include <QSize>
39
#include <QPen>
40

41
#include "vcsliderproperties.h"
42
#include "vcpropertieseditor.h"
43
#include "genericfader.h"
44
#include "fadechannel.h"
45
#include "mastertimer.h"
46
#include "qlcmacros.h"
47
#include "universe.h"
48
#include "vcslider.h"
49
#include "apputil.h"
50
#include "doc.h"
51

52
/** Number of DMXSource cycles to wait to consider a
53
 *  playback value change stable */
54
#define PLAYBACK_CHANGE_THRESHOLD   5  // roughly this is 100ms
55

56
/** +/- value range to catch the slider for external
57
 *  controllers with no feedback support */
58
#define VALUE_CATCHING_THRESHOLD    4
59

60
const quint8 VCSlider::sliderInputSourceId = 0;
61
const quint8 VCSlider::overrideResetInputSourceId = 1;
62
const quint8 VCSlider::flashButtonInputSourceId = 2;
63

64
const QSize VCSlider::defaultSize(QSize(60, 200));
65

66
const QString submasterStyleSheet =
67
    SLIDER_SS_COMMON
68

69
    "QSlider::handle:vertical { "
70
    "background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #4c4c4c, stop:0.45 #2c2c2c, stop:0.50 #000, stop:0.55 #111111, stop:1 #131313);"
71
    "border: 1px solid #5c5c5c;"
72
    "border-radius: 4px; margin: 0 -4px; height: 20px; }"
73

74
    "QSlider::handle:vertical:hover {"
75
    "background: qlineargradient(x1:0, y1:0, x2:0, y2:1, stop:0 #6c6c6c, stop:0.45 #4c4c4c, stop:0.50 #ffff00, stop:0.55 #313131, stop:1 #333333);"
76
    "border: 1px solid #000; }"
77

78
    "QSlider::add-page:vertical { background: QLinearGradient( x1: 0, y1: 0, x2: 1, y2: 0, stop: 0 #77DD73, stop: 1 #A5EC98 );"
79
    "border: 1px solid #5288A7; margin: 0 9px; }";
80

81
/*****************************************************************************
82
 * Initialization
83
 *****************************************************************************/
84

85
VCSlider::VCSlider(QWidget *parent, Doc *doc)
1✔
86
    : VCWidget(parent, doc)
87
    , m_valueDisplayStyle(ExactValue)
88
    , m_catchValues(false)
89
    , m_levelLowLimit(0)
90
    , m_levelHighLimit(UCHAR_MAX)
91
    , m_levelValueChanged(false)
92
    , m_levelValue(0)
93
    , m_monitorEnabled(false)
94
    , m_monitorValue(0)
95
    , m_playbackFunction(Function::invalidId())
2✔
96
    , m_playbackValue(0)
97
    , m_playbackChangeCounter(0)
98
    , m_playbackFlashEnable(false)
99
    , m_playbackIsFlashing(false)
100
    , m_externalMovement(false)
101
    , m_widgetMode(WSlider)
102
    , m_cngType(ClickAndGoWidget::None)
103
    , m_isOverriding(false)
104
    , m_lastInputValue(-1)
1✔
105
{
106
    /* Set the class name "VCSlider" as the object name as well */
107
    setObjectName(VCSlider::staticMetaObject.className());
1✔
108

109
    m_hbox = NULL;
1✔
110
    m_topLabel = NULL;
1✔
111
    m_slider = NULL;
1✔
112
    m_bottomLabel = NULL;
1✔
113

114
    setType(VCWidget::SliderWidget);
1✔
115
    setCaption(QString());
1✔
116
    setFrameStyle(KVCFrameStyleSunken);
1✔
117

118
    /* Main VBox */
119
    new QVBoxLayout(this);
1✔
120

121
    /* Top label */
122
    m_topLabel = new QLabel(this);
1✔
123
    m_topLabel->setAlignment(Qt::AlignHCenter);
1✔
124

125
    layout()->addWidget(m_topLabel);
1✔
126

127
    /* Slider's HBox |stretch|slider|stretch| */
128
    m_hbox = new QHBoxLayout();
1✔
129

130
    /* Put stretchable space before the slider (to its left side) */
131
    m_hbox->addStretch();
1✔
132

133
    /* The slider */
134
    m_slider = new ClickAndGoSlider(this);
1✔
135

136
    m_hbox->addWidget(m_slider);
1✔
137
    m_slider->setRange(0, 255);
1✔
138
    m_slider->setPageStep(1);
1✔
139
    m_slider->setInvertedAppearance(false);
1✔
140
    m_slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
1✔
141
    m_slider->setMinimumWidth(32);
1✔
142
    m_slider->setMaximumWidth(80);
1✔
143
    m_slider->setStyleSheet(CNG_DEFAULT_STYLE);
1✔
144

145
    connect(m_slider, SIGNAL(valueChanged(int)),
1✔
146
            this, SLOT(slotSliderMoved(int)));
147
    connect(this, SIGNAL(requestSliderUpdate(int)),
2✔
148
            m_slider, SLOT(setValue(int)));
1✔
149

150
    /* Put stretchable space after the slider (to its right side) */
151
    m_hbox->addStretch();
1✔
152

153
    layout()->addItem(m_hbox);
1✔
154

155
    /* Click & Go button */
156
    m_cngButton = new QToolButton(this);
1✔
157
    m_cngButton->setFixedSize(48, 48);
1✔
158
    m_cngButton->setIconSize(QSize(42, 42));
1✔
159
    m_menu = new QMenu(this);
1✔
160
    QWidgetAction* action = new QWidgetAction(this);
1✔
161
    m_cngWidget = new ClickAndGoWidget();
1✔
162
    action->setDefaultWidget(m_cngWidget);
1✔
163
    m_menu->addAction(action);
1✔
164
    m_cngButton->setMenu(m_menu);
1✔
165
    m_cngButton->setPopupMode(QToolButton::InstantPopup);
1✔
166
    layout()->addWidget(m_cngButton);
1✔
167
    layout()->setAlignment(m_cngButton, Qt::AlignHCenter);
1✔
168
    m_cngButton->hide();
1✔
169

170
    connect(m_cngWidget, SIGNAL(levelChanged(uchar)),
1✔
171
            this, SLOT(slotClickAndGoLevelChanged(uchar)));
172
    connect(m_cngWidget, SIGNAL(colorChanged(QRgb)),
1✔
173
            this, SLOT(slotClickAndGoColorChanged(QRgb)));
174
    connect(m_cngWidget, SIGNAL(levelAndPresetChanged(uchar,QImage)),
1✔
175
            this, SLOT(slotClickAndGoLevelAndPresetChanged(uchar, QImage)));
176
    connect(this, SIGNAL(monitorDMXValueChanged(int)),
1✔
177
            this, SLOT(slotMonitorDMXValueChanged(int)));
178

179
    m_resetButton = NULL;
1✔
180
    m_flashButton = NULL;
1✔
181

182
    /* Bottom label */
183
    m_bottomLabel = new QLabel(this);
1✔
184
    layout()->addWidget(m_bottomLabel);
1✔
185
    m_bottomLabel->setAlignment(Qt::AlignCenter);
1✔
186
    m_bottomLabel->setWordWrap(true);
1✔
187
    m_bottomLabel->hide();
1✔
188

189
    setMinimumSize(20, 20);
1✔
190
    QSettings settings;
2✔
191
    QVariant var = settings.value(SETTINGS_SLIDER_SIZE);
1✔
192
    if (var.isValid() == true)
1✔
193
        resize(var.toSize());
×
194
    else
195
        resize(VCSlider::defaultSize);
1✔
196

197
    /* Initialize to playback mode by default */
198
    setInvertedAppearance(false);
1✔
199
    m_sliderMode = SliderMode(-1); // avoid use of uninitialized value
1✔
200
    setSliderMode(Playback);
1✔
201

202
    /* Update the slider according to current mode */
203
    slotModeChanged(m_doc->mode());
1✔
204
    setLiveEdit(m_liveEdit);
1✔
205

206
    /* Listen to fixture removals so that LevelChannels can be removed when
207
       they no longer point to an existing fixture->channel */
208
    connect(m_doc, SIGNAL(fixtureRemoved(quint32)),
1✔
209
            this, SLOT(slotFixtureRemoved(quint32)));
210
}
1✔
211

212
VCSlider::~VCSlider()
2✔
213
{
214
    /* When application exits these are already NULL and unregistration
215
       is no longer necessary. But a normal deletion of a VCSlider in
216
       design mode must unregister the slider. */
217
    m_doc->masterTimer()->unregisterDMXSource(this);
1✔
218

219
    // request to delete all the active faders
220
    foreach (QSharedPointer<GenericFader> fader, m_fadersMap.values())
2✔
221
    {
222
        if (!fader.isNull())
×
223
            fader->requestDelete();
×
224
    }
225
    m_fadersMap.clear();
1✔
226
}
2✔
227

228
void VCSlider::setID(quint32 id)
×
229
{
230
    VCWidget::setID(id);
×
231

232
    if (caption().isEmpty())
×
233
        setCaption(tr("Slider %1").arg(id));
×
234
}
×
235

236
/*****************************************************************************
237
 * Clipboard
238
 *****************************************************************************/
239

240
VCWidget* VCSlider::createCopy(VCWidget* parent)
×
241
{
242
    Q_ASSERT(parent != NULL);
×
243

244
    VCSlider* slider = new VCSlider(parent, m_doc);
×
245
    if (slider->copyFrom(this) == false)
×
246
    {
247
        delete slider;
×
248
        slider = NULL;
×
249
    }
250

251
    return slider;
×
252
}
253

254
bool VCSlider::copyFrom(const VCWidget* widget)
×
255
{
256
    const VCSlider* slider = qobject_cast<const VCSlider*> (widget);
×
257
    if (slider == NULL)
×
258
        return false;
×
259

260
    /* Copy widget style */
261
    setWidgetStyle(slider->widgetStyle());
×
262

263
    /* Copy level stuff */
264
    setLevelLowLimit(slider->levelLowLimit());
×
265
    setLevelHighLimit(slider->levelHighLimit());
×
266
    m_levelChannels = slider->m_levelChannels;
×
267

268
    /* Copy playback stuff */
269
    m_playbackFunction = slider->m_playbackFunction;
×
270

271
    /* Copy slider appearance */
272
    setValueDisplayStyle(slider->valueDisplayStyle());
×
273
    setInvertedAppearance(slider->invertedAppearance());
×
274

275
    /* Copy Click & Go feature */
276
    setClickAndGoType(slider->clickAndGoType());
×
277

278
    /* Copy mode & current value */
279
    setSliderMode(slider->sliderMode());
×
280
    setSliderValue(slider->sliderValue());
×
281

282
    /* Copy monitor mode */
283
    setChannelsMonitorEnabled(slider->channelsMonitorEnabled());
×
284

285
    /* Copy flash enabling */
NEW
286
    setPlaybackFlashEnable(slider->playbackFlashEnable());
×
287

288
    /* Copy common stuff */
289
    return VCWidget::copyFrom(widget);
×
290
}
291

292
/*****************************************************************************
293
 * GUI
294
 *****************************************************************************/
295

296
void VCSlider::setCaption(const QString& text)
1✔
297
{
298
    VCWidget::setCaption(text);
1✔
299

300
    if (m_bottomLabel != NULL)
1✔
301
        setBottomLabelText(text);
×
302
}
1✔
303

304
void VCSlider::enableWidgetUI(bool enable)
1✔
305
{
306
    m_topLabel->setEnabled(enable);
1✔
307
    if (m_slider)
1✔
308
        m_slider->setEnabled(enable);
1✔
309
    m_bottomLabel->setEnabled(enable);
1✔
310
    m_cngButton->setEnabled(enable);
1✔
311
    if (m_resetButton)
1✔
312
        m_resetButton->setEnabled(enable);
×
313
    if (m_flashButton)
1✔
NEW
314
        m_flashButton->setEnabled(enable);
×
315
    if (enable == false)
1✔
316
        m_lastInputValue = -1;
1✔
317
}
1✔
318

319
void VCSlider::hideEvent(QHideEvent *)
×
320
{
321
    m_lastInputValue = -1;
×
322
}
×
323

324
/*****************************************************************************
325
 * Properties
326
 *****************************************************************************/
327

328
void VCSlider::editProperties()
×
329
{
330
    VCSliderProperties prop(this, m_doc);
×
331
    if (prop.exec() == QDialog::Accepted)
×
332
    {
333
        m_doc->setModified();
×
334
        if (m_cngType == ClickAndGoWidget::None)
×
335
            m_cngButton->hide();
×
336
        else
337
            m_cngButton->show();
×
338
    }
339
}
×
340

341
/*****************************************************************************
342
 * QLC Mode
343
 *****************************************************************************/
344

345
void VCSlider::slotModeChanged(Doc::Mode mode)
1✔
346
{
347
    if (mode == Doc::Operate)
1✔
348
    {
349
        enableWidgetUI(true);
×
350
        if (m_sliderMode == Level || m_sliderMode == Playback)
×
351
        {
352
            m_doc->masterTimer()->registerDMXSource(this);
×
353
            if (m_sliderMode == Level)
×
354
                m_levelValueChanged = true;
×
355
        }
356
    }
357
    else
358
    {
359
        enableWidgetUI(false);
1✔
360
        if (m_sliderMode == Level || m_sliderMode == Playback)
1✔
361
        {
362
            m_doc->masterTimer()->unregisterDMXSource(this);
1✔
363
            // request to delete all the active faders
364
            foreach (QSharedPointer<GenericFader> fader, m_fadersMap.values())
2✔
365
            {
366
                if (!fader.isNull())
×
367
                    fader->requestDelete();
×
368
            }
369
            m_fadersMap.clear();
1✔
370
        }
371
    }
372

373
    VCWidget::slotModeChanged(mode);
1✔
374
}
1✔
375

376
/*****************************************************************************
377
 * Value display style
378
 *****************************************************************************/
379

380
QString VCSlider::valueDisplayStyleToString(VCSlider::ValueDisplayStyle style)
×
381
{
382
    switch (style)
×
383
    {
384
    case ExactValue:
×
385
        return KXMLQLCVCSliderValueDisplayStyleExact;
×
386
    case PercentageValue:
×
387
        return KXMLQLCVCSliderValueDisplayStylePercentage;
×
388
    default:
×
389
        return QString("Unknown");
×
390
    };
391
}
392

393
VCSlider::ValueDisplayStyle VCSlider::stringToValueDisplayStyle(QString style)
×
394
{
395
    if (style == KXMLQLCVCSliderValueDisplayStyleExact)
×
396
        return ExactValue;
×
397
    else if (style == KXMLQLCVCSliderValueDisplayStylePercentage)
×
398
        return PercentageValue;
×
399
    else
400
        return ExactValue;
×
401
}
402

403
void VCSlider::setValueDisplayStyle(VCSlider::ValueDisplayStyle style)
×
404
{
405
    m_valueDisplayStyle = style;
×
406
    if (m_slider)
×
407
        setTopLabelText(m_slider->value());
×
408
}
×
409

410
VCSlider::ValueDisplayStyle VCSlider::valueDisplayStyle() const
2✔
411
{
412
    return m_valueDisplayStyle;
2✔
413
}
414

415
/*****************************************************************************
416
 * Inverted appearance
417
 *****************************************************************************/
418

419
bool VCSlider::invertedAppearance() const
×
420
{
421
    if (m_slider)
×
422
        return m_slider->invertedAppearance();
×
423

424
    return false;
×
425
}
426

427
void VCSlider::setInvertedAppearance(bool invert)
2✔
428
{
429
    if (m_slider)
2✔
430
    {
431
        m_slider->setInvertedAppearance(invert);
2✔
432
        m_slider->setInvertedControls(invert);
2✔
433
    }
434
}
2✔
435

436
/*********************************************************************
437
 * Value catching feature
438
 *********************************************************************/
439

440
bool VCSlider::catchValues() const
×
441
{
442
    return m_catchValues;
×
443
}
444

445
void VCSlider::setCatchValues(bool enable)
×
446
{
447
    if (enable == m_catchValues)
×
448
        return;
×
449

450
    m_catchValues = enable;
×
451
}
452

453
/*****************************************************************************
454
 * Slider Mode
455
 *****************************************************************************/
456

457
QString VCSlider::sliderModeToString(SliderMode mode)
×
458
{
459
    switch (mode)
×
460
    {
461
        case Level: return QString("Level"); break;
×
462
        case Playback: return QString("Playback"); break;
×
463
        case Submaster: return QString("Submaster"); break;
×
464
        default: return QString("Unknown"); break;
×
465
    }
466
}
467

468
VCSlider::SliderMode VCSlider::stringToSliderMode(const QString& mode)
×
469
{
470
    if (mode == QString("Level"))
×
471
        return Level;
×
472
    else  if (mode == QString("Playback"))
×
473
       return Playback;
×
474
    else //if (mode == QString("Submaster"))
475
        return Submaster;
×
476
}
477

478
VCSlider::SliderMode VCSlider::sliderMode() const
×
479
{
480
    return m_sliderMode;
×
481
}
482

483
void VCSlider::setSliderMode(SliderMode mode)
2✔
484
{
485
    Q_ASSERT(mode >= Level && mode <= Submaster);
2✔
486

487
    m_sliderMode = mode;
2✔
488

489
    if (mode == Level)
2✔
490
    {
491
        /* Set the slider range */
492
        if (m_slider)
×
493
        {
494
            m_slider->setRange(levelLowLimit(), levelHighLimit());
×
495
            m_slider->setValue(levelValue());
×
496
            if (m_widgetMode == WSlider)
×
497
                m_slider->setStyleSheet(CNG_DEFAULT_STYLE);
×
498
        }
499

500
        m_bottomLabel->show();
×
501
        if (m_cngType != ClickAndGoWidget::None)
×
502
        {
503
            setClickAndGoType(m_cngType);
×
504
            setupClickAndGoWidget();
×
505
            m_cngButton->show();
×
506
            if (m_slider)
×
507
                setClickAndGoWidgetFromLevel(m_slider->value());
×
508
        }
509

510
        if (m_doc->mode() == Doc::Operate)
×
511
            m_doc->masterTimer()->registerDMXSource(this);
×
512
    }
513
    else if (mode == Playback)
2✔
514
    {
515
        m_bottomLabel->show();
2✔
516
        m_cngButton->hide();
2✔
517
        m_monitorEnabled = false;
2✔
518

519
        uchar level = playbackValue();
2✔
520
        if (m_slider)
2✔
521
        {
522
            m_slider->setRange(0, UCHAR_MAX);
2✔
523
            m_slider->setValue(level);
2✔
524
            if (m_widgetMode == WSlider)
2✔
525
                m_slider->setStyleSheet(CNG_DEFAULT_STYLE);
2✔
526
        }
527
        slotSliderMoved(level);
2✔
528

529
        if (m_doc->mode() == Doc::Operate)
2✔
530
            m_doc->masterTimer()->registerDMXSource(this);
×
531
        setPlaybackFunction(this->m_playbackFunction);
2✔
532
    }
533
    else if (mode == Submaster)
×
534
    {
535
        m_monitorEnabled = false;
×
536
        setPlaybackFunction(Function::invalidId());
×
537

538
        if (m_slider)
×
539
        {
540
            m_slider->setRange(0, UCHAR_MAX);
×
541
            m_slider->setValue(levelValue());
×
542
            if (m_widgetMode == WSlider)
×
543
                m_slider->setStyleSheet(submasterStyleSheet);
×
544
        }
545
        if (m_doc->mode() == Doc::Operate)
×
546
            m_doc->masterTimer()->unregisterDMXSource(this);
×
547
    }
548
}
2✔
549

550
/*****************************************************************************
551
 * Level
552
 *****************************************************************************/
553

554
void VCSlider::addLevelChannel(quint32 fixture, quint32 channel)
×
555
{
556
    LevelChannel lch(fixture, channel);
×
557

558
    if (m_levelChannels.contains(lch) == false)
×
559
    {
560
        m_levelChannels.append(lch);
×
561
        std::sort(m_levelChannels.begin(), m_levelChannels.end());
×
562
    }
563
}
×
564

565
void VCSlider::removeLevelChannel(quint32 fixture, quint32 channel)
×
566
{
567
    LevelChannel lch(fixture, channel);
×
568
    m_levelChannels.removeAll(lch);
×
569
}
×
570

571
void VCSlider::clearLevelChannels()
×
572
{
573
    m_levelChannels.clear();
×
574
}
×
575

576
QList <VCSlider::LevelChannel> VCSlider::levelChannels()
×
577
{
578
    return m_levelChannels;
×
579
}
580

581
void VCSlider::setLevelLowLimit(uchar value)
×
582
{
583
    m_levelLowLimit = value;
×
584
    if (m_cngWidget != NULL)
×
585
        m_cngWidget->setLevelLowLimit(value);
×
586
}
×
587

588
uchar VCSlider::levelLowLimit() const
×
589
{
590
    return m_levelLowLimit;
×
591
}
592

593
void VCSlider::setLevelHighLimit(uchar value)
×
594
{
595
    m_levelHighLimit = value;
×
596
    if (m_cngWidget != NULL)
×
597
        m_cngWidget->setLevelHighLimit(value);
×
598
}
×
599

600
uchar VCSlider::levelHighLimit() const
×
601
{
602
    return m_levelHighLimit;
×
603
}
604

605
void VCSlider::setChannelsMonitorEnabled(bool enable)
×
606
{
607
    m_monitorEnabled = enable;
×
608

609
    if (m_resetButton != NULL)
×
610
    {
611
        disconnect(m_resetButton, SIGNAL(clicked(bool)),
×
612
                this, SLOT(slotResetButtonClicked()));
613
        delete m_resetButton;
×
614
        m_resetButton = NULL;
×
615
    }
616

617
    if (enable)
×
618
    {
619
        m_resetButton = new QToolButton(this);
×
620
        m_cngButton->setFixedSize(32, 32);
×
621
        m_resetButton->setIconSize(QSize(32, 32));
×
622
        m_resetButton->setStyle(AppUtil::saneStyle());
×
623
        m_resetButton->setIcon(QIcon(":/fileclose.png"));
×
624
        m_resetButton->setToolTip(tr("Reset channels override"));
×
625
        layout()->addWidget(m_resetButton);
×
626
        layout()->setAlignment(m_resetButton, Qt::AlignHCenter);
×
627

628
        connect(m_resetButton, SIGNAL(clicked(bool)),
×
629
                this, SLOT(slotResetButtonClicked()));
630
        m_resetButton->show();
×
631
        setSliderShadowValue(m_monitorValue);
×
632
    }
633
    else
634
    {
635
        setSliderShadowValue(-1);
×
636
    }
637
}
×
638

639
bool VCSlider::channelsMonitorEnabled() const
×
640
{
641
    return m_monitorEnabled;
×
642
}
643

644
void VCSlider::setLevelValue(uchar value, bool external)
×
645
{
646
    QMutexLocker locker(&m_levelValueMutex);
×
647
    m_levelValue = CLAMP(value, levelLowLimit(), levelHighLimit());
×
648
    if (m_monitorEnabled == true)
×
649
        m_monitorValue = m_levelValue;
×
650
    if (m_slider->isSliderDown() || external)
×
651
        m_levelValueChanged = true;
×
652
}
×
653

654
uchar VCSlider::levelValue() const
×
655
{
656
    return m_levelValue;
×
657
}
658

659
void VCSlider::slotFixtureRemoved(quint32 fxi_id)
×
660
{
661
    QMutableListIterator <LevelChannel> it(m_levelChannels);
×
662
    while (it.hasNext() == true)
×
663
    {
664
        it.next();
×
665
        if (it.value().fixture == fxi_id)
×
666
            it.remove();
×
667
    }
668
}
×
669

670
void VCSlider::slotMonitorDMXValueChanged(int value)
×
671
{
672
    if (value == sliderValue())
×
673
        return;
×
674

675
    m_monitorValue = value;
×
676

677
    if (m_isOverriding == false)
×
678
    {
679
        {
680
            QMutexLocker locker(&m_levelValueMutex);
×
681
            m_levelValue = m_monitorValue;
×
682
        }
683

684
        if (m_slider)
×
685
            m_slider->blockSignals(true);
×
686
        setSliderValue(value, false);
×
687
        setTopLabelText(sliderValue());
×
688
        if (m_slider)
×
689
            m_slider->blockSignals(false);
×
690
    }
691
    setSliderShadowValue(value);
×
692
    updateFeedback();
×
693
}
694

695
void VCSlider::slotUniverseWritten(quint32 idx, const QByteArray &universeData)
×
696
{
697
    if (m_levelValueChanged)
×
698
        return;
×
699

700
    bool mixedDMXlevels = false;
×
701
    int monitorSliderValue = -1;
×
702
    QListIterator <LevelChannel> it(m_levelChannels);
×
703

704
    while (it.hasNext() == true)
×
705
    {
706
        LevelChannel lch(it.next());
×
707
        Fixture* fxi = m_doc->fixture(lch.fixture);
×
708
        if (fxi == NULL || fxi->universe() != idx)
×
709
            continue;
×
710

711
        if (lch.channel >= fxi->channels() ||
×
712
            fxi->address() + lch.channel >= (quint32)universeData.length())
×
713
            continue;
×
714

715
        quint32 dmx_ch = fxi->address() + lch.channel;
×
716
        uchar chValue = universeData.at(dmx_ch);
×
717
        if (monitorSliderValue == -1)
×
718
        {
719
            monitorSliderValue = chValue;
×
720
            //qDebug() << "Monitor DMX value:" << monitorSliderValue << "level value:" << m_levelValue;
721
        }
722
        else
723
        {
724
            if (chValue != (uchar)monitorSliderValue)
×
725
            {
726
                mixedDMXlevels = true;
×
727
                // no need to proceed further as mixed values cannot
728
                // be represented by one single slider
729
                break;
×
730
            }
731
        }
732
    }
733

734
    // check if all the DMX channels controlled by this slider
735
    // have the same value. If so, move the widget slider or knob
736
    // to the detected position
737
    if (mixedDMXlevels == false &&
×
738
        monitorSliderValue != m_monitorValue)
×
739
    {
740
        emit monitorDMXValueChanged(monitorSliderValue);
×
741

742
        if (m_isOverriding == false)
×
743
        {
744
            // return here. At the next call of this method,
745
            // the monitor level will kick in
746
            return;
×
747
        }
748
    }
749
}
750

751
/*********************************************************************
752
 * Click & Go
753
 *********************************************************************/
754

755
void VCSlider::setClickAndGoType(ClickAndGoWidget::ClickAndGo type)
×
756
{
757
    m_cngType = type;
×
758
}
×
759

760
ClickAndGoWidget::ClickAndGo VCSlider::clickAndGoType() const
×
761
{
762
    return m_cngType;
×
763
}
764

765
void VCSlider::setupClickAndGoWidget()
×
766
{
767
    if (m_cngWidget != NULL)
×
768
    {
769
        qDebug() << Q_FUNC_INFO << "Level channel: " << m_levelChannels.size() << "type: " << m_cngType;
×
770
        if (m_cngType == ClickAndGoWidget::Preset && m_levelChannels.size() > 0)
×
771
        {
772
            LevelChannel lChan = m_levelChannels.first();
×
773
            Fixture *fxi = m_doc->fixture(lChan.fixture);
×
774
            if (fxi != NULL)
×
775
            {
776
                const QLCChannel *chan = fxi->channel(lChan.channel);
×
777
                m_cngWidget->setType(m_cngType, chan);
×
778
                m_cngWidget->setLevelLowLimit(this->levelLowLimit());
×
779
                m_cngWidget->setLevelHighLimit(this->levelHighLimit());
×
780
            }
781
        }
782
        else
783
            m_cngWidget->setType(m_cngType, NULL);
×
784
    }
785
}
×
786

787
ClickAndGoWidget *VCSlider::getClickAndGoWidget()
×
788
{
789
    return m_cngWidget;
×
790
}
791

792
void VCSlider::setClickAndGoWidgetFromLevel(uchar level)
×
793
{
794
    if (m_cngType == ClickAndGoWidget::None || m_cngWidget == NULL)
×
795
        return;
×
796

797
    if (m_cngType == ClickAndGoWidget::RGB || m_cngType == ClickAndGoWidget::CMY)
×
798
    {
799
        QPixmap px(42, 42);
×
800
        float f = 0;
×
801
        if (m_slider)
×
802
            f = SCALE(float(level), float(m_slider->minimum()),
×
803
                      float(m_slider->maximum()), float(0), float(200));
804

805
        if ((uchar)f == 0)
×
806
        {
807
            px.fill(Qt::black);
×
808
        }
809
        else
810
        {
811
            QColor modColor = m_cngRGBvalue.lighter((uchar)f);
×
812
            px.fill(modColor);
×
813
        }
814
        m_cngButton->setIcon(px);
×
815
    }
816
    else
817
        m_cngButton->setIcon(QPixmap::fromImage(m_cngWidget->getImageFromValue(level)));
×
818
}
819

820
void VCSlider::slotClickAndGoLevelChanged(uchar level)
×
821
{
822
    setSliderValue(level, false, false);
×
823
    updateFeedback();
×
824

825
    QColor col = m_cngWidget->getColorAt(level);
×
826
    QPixmap px(42, 42);
×
827
    px.fill(col);
×
828
    m_cngButton->setIcon(px);
×
829
    m_levelValueChanged = true;
×
830
}
×
831

832
void VCSlider::slotClickAndGoColorChanged(QRgb color)
×
833
{
834
    QColor col(color);
×
835
    m_cngRGBvalue = col;
×
836
    QPixmap px(42, 42);
×
837
    px.fill(col);
×
838
    m_cngButton->setIcon(px);
×
839

840
    // place the slider half way to reach white@255 and black@0
841
    setSliderValue(128);
×
842
    updateFeedback();
×
843

844
    // let's force a value change to cover all the HTP/LTP cases
845
    m_levelValueChanged = true;
×
846
}
×
847

848
void VCSlider::slotClickAndGoLevelAndPresetChanged(uchar level, QImage img)
×
849
{
850
    setSliderValue(level, false, false);
×
851
    updateFeedback();
×
852

853
    QPixmap px = QPixmap::fromImage(img);
×
854
    m_cngButton->setIcon(px);
×
855
    m_levelValueChanged = true;
×
856
}
×
857

858
/*********************************************************************
859
 * Override reset button
860
 *********************************************************************/
861

862
void VCSlider::setOverrideResetKeySequence(const QKeySequence &keySequence)
×
863
{
864
    m_overrideResetKeySequence = QKeySequence(keySequence);
×
865
}
×
866

867
QKeySequence VCSlider::overrideResetKeySequence() const
×
868
{
869
    return m_overrideResetKeySequence;
×
870
}
871

872
void VCSlider::slotResetButtonClicked()
×
873
{
874
    m_isOverriding = false;
×
875
    m_resetButton->setStyleSheet(QString("QToolButton{ background: %1; }")
×
876
                                 .arg(m_slider->palette().window().color().name()));
×
877

878
    // request to delete all the active fader channels
879
    foreach (QSharedPointer<GenericFader> fader, m_fadersMap.values())
×
880
    {
881
        if (!fader.isNull())
×
882
            fader->removeAll();
×
883
    }
884

885
    emit monitorDMXValueChanged(m_monitorValue);
×
886
}
×
887

888
void VCSlider::slotKeyPressed(const QKeySequence &keySequence)
×
889
{
890
    if (isEnabled() == false)
×
891
        return;
×
892

893
    if (m_overrideResetKeySequence == keySequence)
×
894
        slotResetButtonClicked();
×
NEW
895
    else if (m_playbackFlashKeySequence == keySequence)
×
NEW
896
        flashPlayback(true);
×
897
}
898

NEW
899
void VCSlider::slotKeyReleased(const QKeySequence &keySequence)
×
900
{
NEW
901
    if (m_playbackFlashKeySequence == keySequence && m_playbackIsFlashing)
×
NEW
902
        flashPlayback(false);
×
NEW
903
}
×
904

905
/*********************************************************************
906
 * Flash button
907
 *********************************************************************/
908

NEW
909
QKeySequence VCSlider::playbackFlashKeySequence() const
×
910
{
NEW
911
    return m_playbackFlashKeySequence;
×
912
}
913

NEW
914
void VCSlider::setPlaybackFlashKeySequence(const QKeySequence &keySequence)
×
915
{
NEW
916
    m_playbackFlashKeySequence = QKeySequence(keySequence);
×
NEW
917
}
×
918

NEW
919
void VCSlider::mousePressEvent(QMouseEvent *e)
×
920
{
NEW
921
    VCWidget::mousePressEvent(e);
×
922

NEW
923
    if (mode() != Doc::Design && e->button() == Qt::LeftButton &&
×
NEW
924
        m_flashButton && m_flashButton->isDown())
×
925
    {
NEW
926
        flashPlayback(true);
×
927
    }
NEW
928
}
×
929

NEW
930
void VCSlider::mouseReleaseEvent(QMouseEvent *e)
×
931
{
NEW
932
    if (mode() == Doc::Design)
×
933
    {
NEW
934
        VCWidget::mouseReleaseEvent(e);
×
935
    }
NEW
936
    else if (m_playbackIsFlashing)
×
937
    {
NEW
938
        flashPlayback(false);
×
939
    }
UNCOV
940
}
×
941

942
/*****************************************************************************
943
 * Playback
944
 *****************************************************************************/
945

946
void VCSlider::setPlaybackFunction(quint32 fid)
2✔
947
{
948
    Function* old = m_doc->function(m_playbackFunction);
2✔
949
    if (old != NULL)
2✔
950
    {
951
        /* Get rid of old function connections */
952
        disconnect(old, SIGNAL(running(quint32)),
×
953
                this, SLOT(slotPlaybackFunctionRunning(quint32)));
954
        disconnect(old, SIGNAL(stopped(quint32)),
×
955
                this, SLOT(slotPlaybackFunctionStopped(quint32)));
956
        disconnect(old, SIGNAL(attributeChanged(int, qreal)),
×
957
                this, SLOT(slotPlaybackFunctionIntensityChanged(int, qreal)));
958
        if (old->type() == Function::SceneType)
×
959
        {
960
            disconnect(old, SIGNAL(flashing(quint32,bool)),
×
961
                       this, SLOT(slotPlaybackFunctionFlashing(quint32,bool)));
962
        }
963
    }
964

965
    Function* function = m_doc->function(fid);
2✔
966
    if (function != NULL)
2✔
967
    {
968
        /* Connect to the new function */
969
        connect(function, SIGNAL(running(quint32)),
×
970
                this, SLOT(slotPlaybackFunctionRunning(quint32)));
971
        connect(function, SIGNAL(stopped(quint32)),
×
972
                this, SLOT(slotPlaybackFunctionStopped(quint32)));
973
        connect(function, SIGNAL(attributeChanged(int, qreal)),
×
974
                this, SLOT(slotPlaybackFunctionIntensityChanged(int, qreal)));
975
        if (function->type() == Function::SceneType)
×
976
        {
977
            connect(function, SIGNAL(flashing(quint32,bool)),
×
978
                    this, SLOT(slotPlaybackFunctionFlashing(quint32,bool)));
979
        }
980

981
        m_playbackFunction = fid;
×
982
    }
983
    else
984
    {
985
        /* No function attachment */
986
        m_playbackFunction = Function::invalidId();
2✔
987
    }
988
}
2✔
989

990
quint32 VCSlider::playbackFunction() const
×
991
{
992
    return m_playbackFunction;
×
993
}
994

995
void VCSlider::setPlaybackValue(uchar value)
×
996
{
997
    if (m_externalMovement == true || value == m_playbackValue)
×
998
        return;
×
999

1000
    QMutexLocker locker(&m_playbackValueMutex);
×
1001
    m_playbackValue = value;
×
1002
    m_playbackChangeCounter = 5;
×
1003
}
1004

1005
uchar VCSlider::playbackValue() const
2✔
1006
{
1007
    return m_playbackValue;
2✔
1008
}
1009

1010
void VCSlider::notifyFunctionStarting(quint32 fid, qreal functionIntensity)
×
1011
{
1012
    if (mode() == Doc::Design || sliderMode() != Playback)
×
1013
        return;
×
1014

1015
    if (fid == playbackFunction())
×
1016
        return;
×
1017

1018
    if (m_slider != NULL)
×
1019
    {
1020
        int value = SCALE(1.0 - functionIntensity, 0, 1.0,
×
1021
                          m_slider->minimum(), m_slider->maximum());
1022
        if (m_slider->value() > value)
×
1023
        {
1024
            m_externalMovement = true;
×
1025
            m_slider->setValue(value);
×
1026
            m_externalMovement = false;
×
1027

1028
            Function* function = m_doc->function(m_playbackFunction);
×
1029
            if (function != NULL)
×
1030
            {
1031
                qreal pIntensity = qreal(value) / qreal(UCHAR_MAX);
×
1032
                adjustFunctionIntensity(function, pIntensity * intensity());
×
1033
                if (value == 0 && !function->stopped())
×
1034
                    function->stop(functionParent());
×
1035
            }
1036
        }
1037
    }
1038
}
1039

NEW
1040
bool VCSlider::playbackFlashEnable() const
×
1041
{
NEW
1042
    return m_playbackFlashEnable;
×
1043
}
1044

NEW
1045
void VCSlider::setPlaybackFlashEnable(bool enable)
×
1046
{
NEW
1047
    m_playbackFlashEnable = enable;
×
1048

NEW
1049
    if (enable == false && m_flashButton != NULL)
×
1050
    {
NEW
1051
        delete m_flashButton;
×
NEW
1052
        m_flashButton = NULL;
×
1053
    }
NEW
1054
    else if (enable == true && m_flashButton == NULL)
×
1055
    {
NEW
1056
        m_flashButton = new FlashButton(this);
×
NEW
1057
        m_flashButton->setIconSize(QSize(32, 32));
×
NEW
1058
        m_flashButton->setStyle(AppUtil::saneStyle());
×
NEW
1059
        m_flashButton->setIcon(QIcon(":/flash.png"));
×
NEW
1060
        m_flashButton->setToolTip(tr("Flash Function"));
×
NEW
1061
        layout()->addWidget(m_flashButton);
×
NEW
1062
        layout()->setAlignment(m_flashButton, Qt::AlignHCenter);
×
1063

NEW
1064
        m_flashButton->show();
×
1065
    }
NEW
1066
}
×
1067

NEW
1068
void VCSlider::flashPlayback(bool on)
×
1069
{
NEW
1070
    if (on)
×
NEW
1071
        m_playbackFlashPreviousValue = m_playbackValue;
×
NEW
1072
    m_playbackIsFlashing = on;
×
1073

NEW
1074
    setPlaybackValue(on ? UCHAR_MAX : m_playbackFlashPreviousValue);
×
NEW
1075
}
×
1076

UNCOV
1077
void VCSlider::slotPlaybackFunctionRunning(quint32 fid)
×
1078
{
1079
    Q_UNUSED(fid);
1080
}
×
1081

1082
void VCSlider::slotPlaybackFunctionStopped(quint32 fid)
×
1083
{
1084
    if (fid != playbackFunction())
×
1085
        return;
×
1086

1087
    m_externalMovement = true;
×
1088
    if (m_slider)
×
1089
        m_slider->setValue(0);
×
1090
    resetIntensityOverrideAttribute();
×
1091
    updateFeedback();
×
1092
    m_externalMovement = false;
×
1093
}
1094

1095
void VCSlider::slotPlaybackFunctionIntensityChanged(int attrIndex, qreal fraction)
×
1096
{
1097
    //qDebug() << "Function intensity changed" << attrIndex << fraction << m_playbackChangeCounter;
1098

1099
    if (attrIndex != Function::Intensity || m_playbackChangeCounter)
×
1100
        return;
×
1101

1102
    m_externalMovement = true;
×
1103
    if (m_slider)
×
1104
        m_slider->setValue(int(floor((qreal(m_slider->maximum()) * fraction) + 0.5)));
×
1105
    updateFeedback();
×
1106
    m_externalMovement = false;
×
1107
}
1108

1109
void VCSlider::slotPlaybackFunctionFlashing(quint32 fid, bool flashing)
×
1110
{
1111
    if (fid != playbackFunction())
×
1112
        return;
×
1113

1114
    m_externalMovement = true;
×
1115
    if (m_slider)
×
1116
        m_slider->setValue(flashing ? m_slider->maximum() : m_slider->minimum());
×
1117
    updateFeedback();
×
1118
    m_externalMovement = false;
×
1119
}
1120

1121
FunctionParent VCSlider::functionParent() const
×
1122
{
1123
    return FunctionParent(FunctionParent::ManualVCWidget, id());
×
1124
}
1125

1126
/*********************************************************************
1127
 * Submaster
1128
 *********************************************************************/
1129

1130
void VCSlider::emitSubmasterValue()
×
1131
{
1132
    Q_ASSERT(sliderMode() == Submaster);
×
1133

1134
    emit submasterValueChanged(SCALE(float(m_levelValue), float(0),
×
1135
                float(UCHAR_MAX), float(0), float(1)) * intensity());
×
1136
}
×
1137

1138
/*****************************************************************************
1139
 * DMXSource
1140
 *****************************************************************************/
1141

1142
void VCSlider::writeDMX(MasterTimer *timer, QList<Universe *> universes)
×
1143
{
1144
    if (sliderMode() == Level)
×
1145
        writeDMXLevel(timer, universes);
×
1146
    else if (sliderMode() == Playback)
×
1147
        writeDMXPlayback(timer, universes);
×
1148
}
×
1149

1150
void VCSlider::writeDMXLevel(MasterTimer *timer, QList<Universe *> universes)
×
1151
{
1152
    Q_UNUSED(timer);
1153

1154
    QMutexLocker locker(&m_levelValueMutex);
×
1155

1156
    uchar modLevel = m_levelValue;
×
1157
    int r = 0, g = 0, b = 0, c = 0, m = 0, y = 0;
×
1158

1159
    if (m_cngType == ClickAndGoWidget::RGB)
×
1160
    {
1161
        float f = 0;
×
1162
        if (m_slider)
×
1163
            f = SCALE(float(m_levelValue), float(m_slider->minimum()),
×
1164
                      float(m_slider->maximum()), float(0), float(200));
1165

1166
        if (uchar(f) != 0)
×
1167
        {
1168
            QColor modColor = m_cngRGBvalue.lighter(uchar(f));
×
1169
            r = modColor.red();
×
1170
            g = modColor.green();
×
1171
            b = modColor.blue();
×
1172
        }
1173
    }
1174
    else if (m_cngType == ClickAndGoWidget::CMY)
×
1175
    {
1176
        float f = 0;
×
1177
        if (m_slider)
×
1178
            f = SCALE(float(m_levelValue), float(m_slider->minimum()),
×
1179
                      float(m_slider->maximum()), float(0), float(200));
1180
        if (uchar(f) != 0)
×
1181
        {
1182
            QColor modColor = m_cngRGBvalue.lighter(uchar(f));
×
1183
            c = modColor.cyan();
×
1184
            m = modColor.magenta();
×
1185
            y = modColor.yellow();
×
1186
        }
1187
    }
1188

1189
    if (m_levelValueChanged)
×
1190
    {
1191
        QListIterator <LevelChannel> it(m_levelChannels);
×
1192
        while (it.hasNext() == true)
×
1193
        {
1194
            LevelChannel lch(it.next());
×
1195
            Fixture *fxi = m_doc->fixture(lch.fixture);
×
1196
            if (fxi == NULL)
×
1197
                continue;
×
1198

1199
            quint32 universe = fxi->universe();
×
1200

1201
            QSharedPointer<GenericFader> fader = m_fadersMap.value(universe, QSharedPointer<GenericFader>());
×
1202
            if (fader.isNull())
×
1203
            {
1204
                fader = universes[universe]->requestFader(m_monitorEnabled ? Universe::Override : Universe::Auto);
×
1205
                fader->adjustIntensity(intensity());
×
1206
                m_fadersMap[universe] = fader;
×
1207
                if (m_monitorEnabled)
×
1208
                {
1209
                    qDebug() << "VC slider monitor enabled";
×
1210
                    fader->setMonitoring(true);
×
1211
                    connect(fader.data(), SIGNAL(preWriteData(quint32,QByteArray)),
×
1212
                            this, SLOT(slotUniverseWritten(quint32,QByteArray)));
1213
                }
1214
            }
1215

1216
            FadeChannel *fc = fader->getChannelFader(m_doc, universes[universe], lch.fixture, lch.channel);
×
1217
            if (fc->universe() == Universe::invalid())
×
1218
            {
1219
                fader->remove(fc);
×
1220
                continue;
×
1221
            }
1222

1223
            int chType = fc->flags();
×
1224
            const QLCChannel *qlcch = fxi->channel(lch.channel);
×
1225
            if (qlcch == NULL)
×
1226
                continue;
×
1227

1228
            // set override flag if needed
1229
            if (m_isOverriding)
×
1230
                fc->addFlag(FadeChannel::Override);
×
1231

1232
            // request to autoremove LTP channels when set
1233
            if (qlcch->group() != QLCChannel::Intensity)
×
1234
                fc->addFlag(FadeChannel::AutoRemove);
×
1235

1236
            if (chType & FadeChannel::Intensity)
×
1237
            {
1238
                if (m_cngType == ClickAndGoWidget::RGB)
×
1239
                {
1240
                    if (qlcch->colour() == QLCChannel::Red)
×
1241
                        modLevel = uchar(r);
×
1242
                    else if (qlcch->colour() == QLCChannel::Green)
×
1243
                        modLevel = uchar(g);
×
1244
                    else if (qlcch->colour() == QLCChannel::Blue)
×
1245
                        modLevel = uchar(b);
×
1246
                }
1247
                else if (m_cngType == ClickAndGoWidget::CMY)
×
1248
                {
1249
                    if (qlcch->colour() == QLCChannel::Cyan)
×
1250
                        modLevel = uchar(c);
×
1251
                    else if (qlcch->colour() == QLCChannel::Magenta)
×
1252
                        modLevel = uchar(m);
×
1253
                    else if (qlcch->colour() == QLCChannel::Yellow)
×
1254
                        modLevel = uchar(y);
×
1255
                }
1256
            }
1257

1258
            fc->setStart(fc->current());
×
1259
            fc->setTarget(modLevel);
×
1260
            fc->setReady(false);
×
1261
            fc->setElapsed(0);
×
1262

1263
            //qDebug() << "VC Slider write channel" << fc->target();
1264
        }
1265
    }
1266
    m_levelValueChanged = false;
×
1267
}
×
1268

1269
void VCSlider::writeDMXPlayback(MasterTimer* timer, QList<Universe *> ua)
×
1270
{
1271
    Q_UNUSED(ua);
1272

1273
    QMutexLocker locker(&m_playbackValueMutex);
×
1274

1275
    if (m_playbackChangeCounter == 0)
×
1276
        return;
×
1277

1278
    Function* function = m_doc->function(m_playbackFunction);
×
1279
    if (function == NULL || mode() == Doc::Design)
×
1280
        return;
×
1281

1282
    uchar value = m_playbackValue;
×
1283
    qreal pIntensity = qreal(value) / qreal(UCHAR_MAX);
×
1284

1285
    if (value == 0)
×
1286
    {
1287
        // Make sure we ignore the fade out time
1288
        if (function->stopped() == false)
×
1289
        {
1290
            function->stop(functionParent());
×
1291
            resetIntensityOverrideAttribute();
×
1292
        }
1293
    }
1294
    else
1295
    {
1296
        if (function->stopped() == true)
×
1297
        {
1298
#if 0 // temporarily revert #699 until a better solution is found
1299
            // Since this function is started by a fader, its fade in time
1300
            // is decided by the fader movement.
1301
            function->start(timer, functionParent(),
1302
                            0, 0, Function::defaultSpeed(), Function::defaultSpeed());
1303
#endif
1304
            function->start(timer, functionParent());
×
1305
        }
1306
        adjustFunctionIntensity(function, pIntensity * intensity());
×
1307
        emit functionStarting(m_playbackFunction, pIntensity);
×
1308
    }
1309
    m_playbackChangeCounter--;
×
1310
}
1311

1312
/*****************************************************************************
1313
 * Top label
1314
 *****************************************************************************/
1315

1316
void VCSlider::setTopLabelText(int value)
2✔
1317
{
1318
    QString text;
×
1319

1320
    if (valueDisplayStyle() == ExactValue)
2✔
1321
    {
1322
        text = text.asprintf("%.3d", value);
2✔
1323
    }
1324
    else
1325
    {
1326

1327
        float f = 0;
×
1328
        if (m_slider)
×
1329
            f = SCALE(float(value), float(m_slider->minimum()),
×
1330
                      float(m_slider->maximum()), float(0), float(100));
1331
        text = text.asprintf("%.3d%%", static_cast<int> (f));
×
1332
    }
1333
    m_topLabel->setText(text);
2✔
1334
    emit valueChanged(text);
2✔
1335
}
2✔
1336

1337
QString VCSlider::topLabelText()
×
1338
{
1339
    return m_topLabel->text();
×
1340
}
1341

1342
/*****************************************************************************
1343
 * Slider
1344
 *****************************************************************************/
1345

1346
void VCSlider::setSliderValue(uchar value, bool scale, bool external)
×
1347
{
1348
    if (m_slider == NULL)
×
1349
        return;
×
1350

1351
    float val = value;
×
1352

1353
    /* Scale from input value range to this slider's range */
1354
    if (scale)
×
1355
    {
1356
        val = SCALE(float(value), float(0), float(UCHAR_MAX),
×
1357
                float(m_slider->minimum()),
1358
                float(m_slider->maximum()));
1359
    }
1360

1361
    /* Request the UI to update */
1362
    if (m_slider->isSliderDown() == false && val != m_slider->value())
×
1363
       emit requestSliderUpdate(val);
×
1364

1365
    switch (sliderMode())
×
1366
    {
1367
        case Level:
×
1368
        {
1369
            if (m_monitorEnabled == true && m_isOverriding == false && m_slider->isSliderDown())
×
1370
            {
1371
                m_resetButton->setStyleSheet(QString("QToolButton{ background: red; }"));
×
1372
                m_isOverriding = true;
×
1373
            }
1374
            setLevelValue(val, external);
×
1375
            setClickAndGoWidgetFromLevel(val);
×
1376
        }
1377
        break;
×
1378

1379
        case Playback:
×
1380
        {
1381
            setPlaybackValue(value);
×
1382
        }
1383
        break;
×
1384

1385
        case Submaster:
×
1386
        {
1387
            setLevelValue(val);
×
1388
            emitSubmasterValue();
×
1389
        }
1390
        break;
×
1391
    }
1392
}
1393

1394
void VCSlider::setSliderShadowValue(int value)
×
1395
{
1396
    if (m_widgetMode == WSlider)
×
1397
    {
1398
        ClickAndGoSlider *sl = qobject_cast<ClickAndGoSlider*> (m_slider);
×
1399
        sl->setShadowLevel(value);
×
1400
    }
1401
}
×
1402

1403
int VCSlider::sliderValue() const
×
1404
{
1405
    if (m_slider)
×
1406
        return m_slider->value();
×
1407

1408
    return 0;
×
1409
}
1410

1411
void VCSlider::setWidgetStyle(SliderWidgetStyle mode)
×
1412
{
1413
    if (mode == m_widgetMode)
×
1414
        return;
×
1415

1416
    if (mode == WKnob)
×
1417
    {
1418
        qDebug() << "Switching to knob widget";
×
1419
        disconnect(m_slider, SIGNAL(valueChanged(int)),
×
1420
                this, SLOT(slotSliderMoved(int)));
1421

1422
        QLayoutItem* item;
1423
        while ((item = m_hbox->takeAt(0)) != NULL)
×
1424
        {
1425
            delete item->widget();
×
1426
            delete item;
×
1427
        }
1428

1429
        m_slider = NULL;
×
1430

1431
        m_slider = new KnobWidget(this);
×
1432
        m_slider->setEnabled(false);
×
1433
        m_slider->setRange(levelLowLimit(), levelHighLimit());
×
1434
        m_hbox->addWidget(m_slider);
×
1435
        m_slider->show();
×
1436
        connect(m_slider, SIGNAL(valueChanged(int)),
×
1437
                this, SLOT(slotSliderMoved(int)));
1438
    }
1439
    else if (mode == WSlider)
×
1440
    {
1441
        qDebug() << "Switching to slider widget";
×
1442
        disconnect(m_slider, SIGNAL(valueChanged(int)),
×
1443
                this, SLOT(slotSliderMoved(int)));
1444

1445
        QLayoutItem* item;
1446
        while ((item = m_hbox->takeAt(0)) != NULL)
×
1447
        {
1448
            delete item->widget();
×
1449
            delete item;
×
1450
        }
1451

1452
        m_slider = NULL;
×
1453
        m_hbox->addStretch();
×
1454
        m_slider = new ClickAndGoSlider(this);
×
1455
        m_slider->setEnabled(false);
×
1456
        m_slider->setRange(levelLowLimit(), levelHighLimit());
×
1457
        m_hbox->addWidget(m_slider);
×
1458
        m_slider->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
×
1459
        m_slider->setMinimumWidth(32);
×
1460
        m_slider->setMaximumWidth(80);
×
1461
        m_slider->setStyleSheet(CNG_DEFAULT_STYLE);
×
1462
        m_hbox->addStretch();
×
1463
        m_slider->show();
×
1464
        connect(m_slider, SIGNAL(valueChanged(int)),
×
1465
                this, SLOT(slotSliderMoved(int)));
1466
    }
1467
    connect(this, SIGNAL(requestSliderUpdate(int)),
×
1468
            m_slider, SLOT(setValue(int)));
×
1469
    m_widgetMode = mode;
×
1470
    update();
×
1471
}
1472

1473
VCSlider::SliderWidgetStyle VCSlider::widgetStyle() const
×
1474
{
1475
    return m_widgetMode;
×
1476
}
1477

1478
QString VCSlider::widgetStyleToString(VCSlider::SliderWidgetStyle style)
×
1479
{
1480
    if (style == VCSlider::WSlider)
×
1481
        return QString("Slider");
×
1482
    else if (style == VCSlider::WKnob)
×
1483
        return QString("Knob");
×
1484

1485
    return QString();
×
1486
}
1487

1488
VCSlider::SliderWidgetStyle VCSlider::stringToWidgetStyle(QString style)
×
1489
{
1490
    if (style == "Slider")
×
1491
        return VCSlider::WSlider;
×
1492
    else if (style == "Knob")
×
1493
        return VCSlider::WKnob;
×
1494

1495
    return VCSlider::WSlider;
×
1496
}
1497

1498
void VCSlider::updateFeedback()
×
1499
{
1500
    int fbv = 0;
×
1501
    if (m_slider)
×
1502
    {
1503
        if (invertedAppearance() == true)
×
1504
            fbv = m_slider->maximum() - m_slider->value() + m_slider->minimum();
×
1505
        else
1506
            fbv = m_slider->value();
×
1507
        fbv = int(SCALE(float(fbv), float(m_slider->minimum()),
×
1508
                        float(m_slider->maximum()), float(0), float(UCHAR_MAX)));
1509
    }
1510
    sendFeedback(fbv);
×
1511
}
×
1512

1513
void VCSlider::slotSliderMoved(int value)
2✔
1514
{
1515
    /* Set text for the top label */
1516
    setTopLabelText(value);
2✔
1517

1518
    /* Do the rest only if the slider is being moved by the user */
1519
    if (m_slider->isSliderDown() == false)
2✔
1520
        return;
2✔
1521

1522
    setSliderValue(value, false);
×
1523

1524
    updateFeedback();
×
1525
}
1526

1527
/*****************************************************************************
1528
 * Bottom label
1529
 *****************************************************************************/
1530
void VCSlider::setBottomLabelText(const QString& text)
×
1531
{
1532
    m_bottomLabel->setText(text);
×
1533
}
×
1534

1535
QString VCSlider::bottomLabelText()
×
1536
{
1537
    return m_bottomLabel->text();
×
1538
}
1539

1540
/*****************************************************************************
1541
 * External input
1542
 *****************************************************************************/
1543

1544
void VCSlider::slotInputValueChanged(quint32 universe, quint32 channel, uchar value)
×
1545
{
1546
    /* Don't let input data through in design mode or if disabled */
1547
    if (acceptsInput() == false)
×
1548
        return;
×
1549

1550
    quint32 pagedCh = (page() << 16) | channel;
×
1551

1552
    if (checkInputSource(universe, pagedCh, value, sender(), sliderInputSourceId))
×
1553
    {
1554
        if (m_slider)
×
1555
        {
1556
            /* When 'values catching" is enabled, controllers that do not have motorized faders
1557
             * can catch up with the current slider value by entering a certain threshold
1558
             * or by 'surpassing' the current value */
1559
            if (catchValues())
×
1560
            {
1561
                uchar currentValue = sliderValue();
×
1562

1563
                // filter 'out of threshold' cases
1564
                if (m_lastInputValue == -1 ||
×
1565
                    (m_lastInputValue < currentValue - VALUE_CATCHING_THRESHOLD && value < currentValue - VALUE_CATCHING_THRESHOLD) ||
×
1566
                    (m_lastInputValue > currentValue + VALUE_CATCHING_THRESHOLD && value > currentValue + VALUE_CATCHING_THRESHOLD))
×
1567
                {
1568
                    m_lastInputValue = value;
×
1569
                    return;
×
1570
                }
1571
            }
1572

1573
            if (m_monitorEnabled == true && m_isOverriding == false)
×
1574
            {
1575
                m_resetButton->setStyleSheet(QString("QToolButton{ background: red; }"));
×
1576
                m_isOverriding = true;
×
1577
            }
1578

1579
            if (invertedAppearance())
×
1580
                value = UCHAR_MAX - value;
×
1581

1582
            setSliderValue(value, true, true);
×
1583
            m_lastInputValue = value;
×
1584
        }
1585
    }
1586
    else if (checkInputSource(universe, pagedCh, value, sender(), overrideResetInputSourceId))
×
1587
    {
1588
        if (value > 0)
×
1589
            slotResetButtonClicked();
×
1590
    }
NEW
1591
    else if (checkInputSource(universe, pagedCh, value, sender(), flashButtonInputSourceId))
×
1592
    {
NEW
1593
        flashPlayback(value ? true : false);
×
1594
    }
1595
}
1596

1597
void VCSlider::adjustIntensity(qreal val)
×
1598
{
1599
    VCWidget::adjustIntensity(val);
×
1600

1601
    if (sliderMode() == Playback)
×
1602
    {
1603
        Function* function = m_doc->function(m_playbackFunction);
×
1604
        if (function == NULL || mode() == Doc::Design)
×
1605
            return;
×
1606

1607
        qreal pIntensity = qreal(m_playbackValue) / qreal(UCHAR_MAX);
×
1608
        adjustFunctionIntensity(function, pIntensity * intensity());
×
1609
    }
1610
    else if (sliderMode() == Level)
×
1611
    {
1612
        foreach (QSharedPointer<GenericFader> fader, m_fadersMap.values())
×
1613
        {
1614
            if (!fader.isNull())
×
1615
                fader->adjustIntensity(val);
×
1616
        }
1617
    }
1618
}
1619

1620
/*****************************************************************************
1621
 * Load & Save
1622
 *****************************************************************************/
1623

1624
bool VCSlider::loadXML(QXmlStreamReader &root)
1✔
1625
{
1626
    bool visible = false;
1✔
1627
    int x = 0;
1✔
1628
    int y = 0;
1✔
1629
    int w = 0;
1✔
1630
    int h = 0;
1✔
1631

1632
    SliderMode sliderMode = Playback;
1✔
1633
    QString str;
1✔
1634

1635
    if (root.name() != KXMLQLCVCSlider)
1✔
1636
    {
1637
        qWarning() << Q_FUNC_INFO << "Slider node not found";
×
1638
        return false;
×
1639
    }
1640

1641
    /* Widget commons */
1642
    loadXMLCommon(root);
1✔
1643

1644
    QXmlStreamAttributes attrs = root.attributes();
1✔
1645

1646
    /* Widget style */
1647
    if (attrs.hasAttribute(KXMLQLCVCSliderWidgetStyle))
1✔
1648
        setWidgetStyle(stringToWidgetStyle(attrs.value(KXMLQLCVCSliderWidgetStyle).toString()));
×
1649

1650
    if (attrs.value(KXMLQLCVCSliderInvertedAppearance).toString() == "false")
1✔
1651
        setInvertedAppearance(false);
×
1652
    else
1653
        setInvertedAppearance(true);
1✔
1654

1655
    /* Values catching */
1656
    if (attrs.hasAttribute(KXMLQLCVCSliderCatchValues))
1✔
1657
        setCatchValues(true);
×
1658

1659
    /* Children */
1660
    while (root.readNextStartElement())
1✔
1661
    {
1662
        //qDebug() << "VC Slider tag:" << root.name();
1663
        if (root.name() == KXMLQLCWindowState)
×
1664
        {
1665
            loadXMLWindowState(root, &x, &y, &w, &h, &visible);
×
1666
            setGeometry(x, y, w, h);
×
1667
        }
1668
        else if (root.name() == KXMLQLCVCWidgetAppearance)
×
1669
        {
1670
            loadXMLAppearance(root);
×
1671
        }
1672
        else if (root.name() == KXMLQLCVCSliderMode)
×
1673
        {
1674
            QXmlStreamAttributes mAttrs = root.attributes();
×
1675
            sliderMode = stringToSliderMode(root.readElementText());
×
1676

1677
            str = mAttrs.value(KXMLQLCVCSliderValueDisplayStyle).toString();
×
1678
            setValueDisplayStyle(stringToValueDisplayStyle(str));
×
1679

1680
            if (mAttrs.hasAttribute(KXMLQLCVCSliderClickAndGoType))
×
1681
            {
1682
                str = mAttrs.value(KXMLQLCVCSliderClickAndGoType).toString();
×
1683
                setClickAndGoType(ClickAndGoWidget::stringToClickAndGoType(str));
×
1684
            }
1685

1686
            if (mAttrs.hasAttribute(KXMLQLCVCSliderLevelMonitor))
×
1687
            {
1688
                if (mAttrs.value(KXMLQLCVCSliderLevelMonitor).toString() == "false")
×
1689
                    setChannelsMonitorEnabled(false);
×
1690
                else
1691
                    setChannelsMonitorEnabled(true);
×
1692
            }
1693
        }
1694
        else if (root.name() == KXMLQLCVCSliderOverrideReset)
×
1695
        {
1696
            QString str = loadXMLSources(root, overrideResetInputSourceId);
×
1697
            if (str.isEmpty() == false)
×
1698
                m_overrideResetKeySequence = stripKeySequence(QKeySequence(str));
×
1699
        }
1700
        else if (root.name() == KXMLQLCVCSliderLevel)
×
1701
        {
1702
            loadXMLLevel(root);
×
1703
        }
1704
        else if (root.name() == KXMLQLCVCWidgetInput)
×
1705
        {
1706
            loadXMLInput(root);
×
1707
        }
1708
        else if (root.name() == KXMLQLCVCSliderPlayback)
×
1709
        {
1710
            loadXMLPlayback(root);
×
1711
        }
1712
        else
1713
        {
1714
            qWarning() << Q_FUNC_INFO << "Unknown slider tag:" << root.name().toString();
×
1715
            root.skipCurrentElement();
×
1716
        }
1717
    }
1718

1719
    /* Set the mode last, after everything else has been set */
1720
    setSliderMode(sliderMode);
1✔
1721

1722
    return true;
1✔
1723
}
1724

1725
bool VCSlider::loadXMLLevel(QXmlStreamReader &level_root)
×
1726
{
1727
    QString str;
×
1728

1729
    if (level_root.name() != KXMLQLCVCSliderLevel)
×
1730
    {
1731
        qWarning() << Q_FUNC_INFO << "Slider level node not found";
×
1732
        return false;
×
1733
    }
1734

1735
    QXmlStreamAttributes attrs = level_root.attributes();
×
1736

1737
    /* Level low limit */
1738
    str = attrs.value(KXMLQLCVCSliderLevelLowLimit).toString();
×
1739
    setLevelLowLimit(str.toInt());
×
1740

1741
    /* Level high limit */
1742
    str = attrs.value(KXMLQLCVCSliderLevelHighLimit).toString();
×
1743
    setLevelHighLimit(str.toInt());
×
1744

1745
    /* Level value */
1746
    str = attrs.value(KXMLQLCVCSliderLevelValue).toString();
×
1747
    setLevelValue(str.toInt());
×
1748

1749
    QXmlStreamReader::TokenType tType = level_root.readNext();
×
1750

1751
    if (tType == QXmlStreamReader::EndElement)
×
1752
    {
1753
        level_root.readNext();
×
1754
        return true;
×
1755
    }
1756

1757
    if (tType == QXmlStreamReader::Characters)
×
1758
        tType = level_root.readNext();
×
1759

1760
    // check if there is a Channel tag defined
1761
    if (tType == QXmlStreamReader::StartElement)
×
1762
    {
1763
        /* Children */
1764
        do
×
1765
        {
1766
            if (level_root.name() == KXMLQLCVCSliderChannel)
×
1767
            {
1768
                /* Fixture & channel */
1769
                str = level_root.attributes().value(KXMLQLCVCSliderChannelFixture).toString();
×
1770
                addLevelChannel(
×
1771
                    static_cast<quint32>(str.toInt()),
×
1772
                    static_cast<quint32> (level_root.readElementText().toInt()));
×
1773
            }
1774
            else
1775
            {
1776
                qWarning() << Q_FUNC_INFO << "Unknown slider level tag:" << level_root.name().toString();
×
1777
                level_root.skipCurrentElement();
×
1778
            }
1779
        } while (level_root.readNextStartElement());
×
1780
    }
1781

1782
    return true;
×
1783
}
1784

1785
bool VCSlider::loadXMLPlayback(QXmlStreamReader &pb_root)
×
1786
{
1787
    if (pb_root.name() != KXMLQLCVCSliderPlayback)
×
1788
    {
1789
        qWarning() << Q_FUNC_INFO << "Slider playback node not found";
×
1790
        return false;
×
1791
    }
1792

1793
    /* Children */
1794
    while (pb_root.readNextStartElement())
×
1795
    {
1796
        if (pb_root.name() == KXMLQLCVCSliderPlaybackFunction)
×
1797
        {
1798
            /* Function */
1799
            setPlaybackFunction(pb_root.readElementText().toUInt());
×
1800
        }
NEW
1801
        else if (pb_root.name() == KXMLQLCVCSliderPlaybackFlash)
×
1802
        {
NEW
1803
            setPlaybackFlashEnable(true);
×
NEW
1804
            QString str = loadXMLSources(pb_root, flashButtonInputSourceId);
×
NEW
1805
            if (str.isEmpty() == false)
×
NEW
1806
                m_playbackFlashKeySequence = stripKeySequence(QKeySequence(str));
×
1807
        }
1808
        else
1809
        {
1810
            qWarning() << Q_FUNC_INFO << "Unknown slider playback tag:" << pb_root.name().toString();
×
1811
            pb_root.skipCurrentElement();
×
1812
        }
1813
    }
1814

1815
    return true;
×
1816
}
1817

1818
bool VCSlider::saveXML(QXmlStreamWriter *doc)
×
1819
{
1820
    QString str;
×
1821

1822
    Q_ASSERT(doc != NULL);
×
1823

1824
    /* VC Slider entry */
1825
    doc->writeStartElement(KXMLQLCVCSlider);
×
1826

1827
    saveXMLCommon(doc);
×
1828

1829
    /* Widget style */
1830
    doc->writeAttribute(KXMLQLCVCSliderWidgetStyle, widgetStyleToString(widgetStyle()));
×
1831

1832
    /* Inverted appearance */
1833
    if (invertedAppearance() == true)
×
1834
        doc->writeAttribute(KXMLQLCVCSliderInvertedAppearance, "true");
×
1835
    else
1836
        doc->writeAttribute(KXMLQLCVCSliderInvertedAppearance, "false");
×
1837

1838
    /* Values catching */
1839
    if (catchValues() == true)
×
1840
        doc->writeAttribute(KXMLQLCVCSliderCatchValues, "true");
×
1841

1842
    /* Window state */
1843
    saveXMLWindowState(doc);
×
1844

1845
    /* Appearance */
1846
    saveXMLAppearance(doc);
×
1847

1848
    /* External input */
1849
    saveXMLInput(doc, inputSource(sliderInputSourceId));
×
1850

1851
    /* SliderMode */
1852
    doc->writeStartElement(KXMLQLCVCSliderMode);
×
1853

1854
    /* Value display style */
1855
    str = valueDisplayStyleToString(valueDisplayStyle());
×
1856
    doc->writeAttribute(KXMLQLCVCSliderValueDisplayStyle, str);
×
1857

1858
    /* Click And Go type */
1859
    str = ClickAndGoWidget::clickAndGoTypeToString(m_cngType);
×
1860
    doc->writeAttribute(KXMLQLCVCSliderClickAndGoType, str);
×
1861

1862
    /* Monitor channels */
1863
    if (sliderMode() == Level)
×
1864
    {
1865
        if (channelsMonitorEnabled() == true)
×
1866
            doc->writeAttribute(KXMLQLCVCSliderLevelMonitor, "true");
×
1867
        else
1868
            doc->writeAttribute(KXMLQLCVCSliderLevelMonitor, "false");
×
1869
    }
1870

1871
    doc->writeCharacters(sliderModeToString(m_sliderMode));
×
1872

1873
    /* End the <SliderMode> tag */
1874
    doc->writeEndElement();
×
1875

1876
    if (sliderMode() == Level && channelsMonitorEnabled() == true)
×
1877
    {
1878
        doc->writeStartElement(KXMLQLCVCSliderOverrideReset);
×
1879
        if (m_overrideResetKeySequence.toString().isEmpty() == false)
×
1880
            doc->writeTextElement(KXMLQLCVCWidgetKey, m_overrideResetKeySequence.toString());
×
1881
        saveXMLInput(doc, inputSource(overrideResetInputSourceId));
×
1882
        doc->writeEndElement();
×
1883
    }
1884

1885
    /* Level */
1886
    doc->writeStartElement(KXMLQLCVCSliderLevel);
×
1887
    /* Level low limit */
1888
    doc->writeAttribute(KXMLQLCVCSliderLevelLowLimit, QString::number(levelLowLimit()));
×
1889
    /* Level high limit */
1890
    doc->writeAttribute(KXMLQLCVCSliderLevelHighLimit, QString::number(levelHighLimit()));
×
1891
    /* Level value */
1892
    doc->writeAttribute(KXMLQLCVCSliderLevelValue, QString::number(levelValue()));
×
1893

1894
    /* Level channels */
1895
    QListIterator <LevelChannel> it(m_levelChannels);
×
1896
    while (it.hasNext() == true)
×
1897
    {
1898
        LevelChannel lch(it.next());
×
1899
        lch.saveXML(doc);
×
1900
    }
1901

1902
    /* End the <Level> tag */
1903
    doc->writeEndElement();
×
1904

1905
    /* Playback */
1906
    doc->writeStartElement(KXMLQLCVCSliderPlayback);
×
1907
    /* Playback function */
1908
    doc->writeTextElement(KXMLQLCVCSliderPlaybackFunction, QString::number(playbackFunction()));
×
1909

NEW
1910
    if (sliderMode() == Playback && playbackFlashEnable() == true)
×
1911
    {
NEW
1912
        doc->writeStartElement(KXMLQLCVCSliderPlaybackFlash);
×
NEW
1913
        if (m_playbackFlashKeySequence.toString().isEmpty() == false)
×
NEW
1914
            doc->writeTextElement(KXMLQLCVCWidgetKey, m_playbackFlashKeySequence.toString());
×
NEW
1915
        saveXMLInput(doc, inputSource(flashButtonInputSourceId));
×
NEW
1916
        doc->writeEndElement();
×
1917
    }
1918

1919
    /* End the <Playback> tag */
1920
    doc->writeEndElement();
×
1921

1922
    /* End the <Slider> tag */
1923
    doc->writeEndElement();
×
1924

1925
    return true;
×
1926
}
1927

1928
/****************************************************************************
1929
 * LevelChannel implementation
1930
 ****************************************************************************/
1931

1932
VCSlider::LevelChannel::LevelChannel(quint32 fid, quint32 ch)
×
1933
{
1934
    this->fixture = fid;
×
1935
    this->channel = ch;
×
1936
}
×
1937

1938
VCSlider::LevelChannel::LevelChannel(const LevelChannel& lc)
×
1939
{
1940
    *this = lc;
×
1941
}
×
1942

1943
VCSlider::LevelChannel &VCSlider::LevelChannel::operator=(const VCSlider::LevelChannel &lc)
×
1944
{
1945
    if (this != &lc)
×
1946
    {
1947
        this->fixture = lc.fixture;
×
1948
        this->channel = lc.channel;
×
1949
    }
1950

1951
    return *this;
×
1952
}
1953

1954
bool VCSlider::LevelChannel::operator==(const LevelChannel& lc) const
×
1955
{
1956
    return (this->fixture == lc.fixture && this->channel == lc.channel);
×
1957
}
1958

1959
bool VCSlider::LevelChannel::operator<(const LevelChannel& lc) const
×
1960
{
1961
    if (this->fixture < lc.fixture)
×
1962
        return true;
×
1963
    else if (this->fixture == lc.fixture && this->channel < lc.channel)
×
1964
        return true;
×
1965
    else
1966
        return false;
×
1967
}
1968

1969
void VCSlider::LevelChannel::saveXML(QXmlStreamWriter *doc) const
×
1970
{
1971
    Q_ASSERT(doc != NULL);
×
1972

1973
    doc->writeStartElement(KXMLQLCVCSliderChannel);
×
1974

1975
    doc->writeAttribute(KXMLQLCVCSliderChannelFixture,
×
1976
                       QString::number(this->fixture));
×
1977

1978
    doc->writeCharacters(QString::number(this->channel));
×
1979
    doc->writeEndElement();
×
1980
}
×
1981

NEW
1982
void VCSlider::FlashButton::mousePressEvent(QMouseEvent *e)
×
1983
{
NEW
1984
    QToolButton::mousePressEvent(e);
×
1985
    // ignore event so that it can be
1986
    // forwarded to parent widget
NEW
1987
    e->ignore();
×
NEW
1988
}
×
1989

NEW
1990
void VCSlider::FlashButton::mouseReleaseEvent(QMouseEvent *e)
×
1991
{
NEW
1992
    QToolButton::mouseReleaseEvent(e);
×
1993
    // ignore event so that it can be
1994
    // forwarded to parent widget
NEW
1995
    e->ignore();
×
NEW
1996
}
×
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