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

mcallegari / qlcplus / 13633248611

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

push

github

web-flow
actions: add chrpath to profile

14689 of 46089 relevant lines covered (31.87%)

26426.11 hits per line

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

17.71
/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)
1✔
88
    , m_catchValues(false)
1✔
89
    , m_levelLowLimit(0)
1✔
90
    , m_levelHighLimit(UCHAR_MAX)
1✔
91
    , m_levelValueChanged(false)
1✔
92
    , m_levelValue(0)
1✔
93
    , m_monitorEnabled(false)
1✔
94
    , m_monitorValue(0)
1✔
95
    , m_playbackFunction(Function::invalidId())
1✔
96
    , m_playbackValue(0)
1✔
97
    , m_playbackChangeCounter(0)
1✔
98
    , m_playbackFlashEnable(false)
1✔
99
    , m_playbackIsFlashing(false)
1✔
100
    , m_externalMovement(false)
1✔
101
    , m_widgetMode(WSlider)
1✔
102
    , m_cngType(ClickAndGoWidget::None)
1✔
103
    , m_isOverriding(false)
1✔
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)),
1✔
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;
1✔
191
    QVariant var = settings.value(SETTINGS_SLIDER_SIZE);
2✔
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 */
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✔
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);
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
    updateOverrideFeedback(false);
×
885

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

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

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

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

906
/*********************************************************************
907
 * Flash button
908
 *********************************************************************/
909

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

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

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

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

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

943
/*****************************************************************************
944
 * Playback
945
 *****************************************************************************/
946

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1127
/*********************************************************************
1128
 * Submaster
1129
 *********************************************************************/
1130

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

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

1139
/*****************************************************************************
1140
 * DMXSource
1141
 *****************************************************************************/
1142

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

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

1155
    QMutexLocker locker(&m_levelValueMutex);
×
1156

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1274
    QMutexLocker locker(&m_playbackValueMutex);
×
1275

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

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

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

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

1313
/*****************************************************************************
1314
 * Top label
1315
 *****************************************************************************/
1316

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

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

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

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

1343
/*****************************************************************************
1344
 * Slider
1345
 *****************************************************************************/
1346

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

1352
    float val = value;
×
1353

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

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

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

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

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

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

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

1410
    return 0;
1411
}
1412

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

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

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

1431
        m_slider = NULL;
×
1432

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

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

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

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

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

1487
    return QString();
1488
}
1489

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

1497
    return VCSlider::WSlider;
1498
}
1499

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

1515
void VCSlider::updateOverrideFeedback(bool on)
×
1516
{
1517
    QSharedPointer<QLCInputSource> src = inputSource(overrideResetInputSourceId);
×
1518
    if (!src.isNull() && src->isValid() == true)
×
1519
        sendFeedback(src->feedbackValue(on ? QLCInputFeedback::UpperValue : QLCInputFeedback::LowerValue), overrideResetInputSourceId);
×
1520
}
×
1521

1522
void VCSlider::slotSliderMoved(int value)
2✔
1523
{
1524
    /* Set text for the top label */
1525
    setTopLabelText(value);
2✔
1526

1527
    /* Do the rest only if the slider is being moved by the user */
1528
    if (m_slider->isSliderDown() == false)
2✔
1529
        return;
1530

1531
    setSliderValue(value, false);
×
1532

1533
    updateFeedback();
×
1534
}
1535

1536
/*****************************************************************************
1537
 * Bottom label
1538
 *****************************************************************************/
1539
void VCSlider::setBottomLabelText(const QString& text)
×
1540
{
1541
    m_bottomLabel->setText(text);
×
1542
}
×
1543

1544
QString VCSlider::bottomLabelText()
×
1545
{
1546
    return m_bottomLabel->text();
×
1547
}
1548

1549
/*****************************************************************************
1550
 * External input
1551
 *****************************************************************************/
1552

1553
void VCSlider::slotInputValueChanged(quint32 universe, quint32 channel, uchar value)
×
1554
{
1555
    /* Don't let input data through in design mode or if disabled */
1556
    if (acceptsInput() == false)
×
1557
        return;
1558

1559
    quint32 pagedCh = (page() << 16) | channel;
×
1560

1561
    if (checkInputSource(universe, pagedCh, value, sender(), sliderInputSourceId))
×
1562
    {
1563
        if (m_slider)
×
1564
        {
1565
            /* When 'values catching" is enabled, controllers that do not have motorized faders
1566
             * can catch up with the current slider value by entering a certain threshold
1567
             * or by 'surpassing' the current value */
1568
            if (catchValues())
×
1569
            {
1570
                uchar currentValue = sliderValue();
×
1571

1572
                // filter 'out of threshold' cases
1573
                if (m_lastInputValue == -1 ||
×
1574
                    (m_lastInputValue < currentValue - VALUE_CATCHING_THRESHOLD && value < currentValue - VALUE_CATCHING_THRESHOLD) ||
×
1575
                    (m_lastInputValue > currentValue + VALUE_CATCHING_THRESHOLD && value > currentValue + VALUE_CATCHING_THRESHOLD))
×
1576
                {
1577
                    m_lastInputValue = value;
×
1578
                    return;
×
1579
                }
1580
            }
1581

1582
            if (m_monitorEnabled == true && m_isOverriding == false)
×
1583
            {
1584
                m_resetButton->setStyleSheet(QString("QToolButton{ background: red; }"));
×
1585
                m_isOverriding = true;
×
1586
                updateOverrideFeedback(true);
×
1587
            }
1588

1589
            if (invertedAppearance())
×
1590
                value = UCHAR_MAX - value;
×
1591

1592
            setSliderValue(value, true, true);
×
1593
            m_lastInputValue = value;
×
1594
        }
1595
    }
1596
    else if (checkInputSource(universe, pagedCh, value, sender(), overrideResetInputSourceId))
×
1597
    {
1598
        if (value > 0)
×
1599
            slotResetButtonClicked();
×
1600
    }
1601
    else if (checkInputSource(universe, pagedCh, value, sender(), flashButtonInputSourceId))
×
1602
    {
1603
        flashPlayback(value ? true : false);
×
1604
    }
1605
}
1606

1607
void VCSlider::adjustIntensity(qreal val)
×
1608
{
1609
    VCWidget::adjustIntensity(val);
×
1610

1611
    if (sliderMode() == Playback)
×
1612
    {
1613
        Function* function = m_doc->function(m_playbackFunction);
×
1614
        if (function == NULL || mode() == Doc::Design)
×
1615
            return;
×
1616

1617
        qreal pIntensity = qreal(m_playbackValue) / qreal(UCHAR_MAX);
×
1618
        adjustFunctionIntensity(function, pIntensity * intensity());
×
1619
    }
1620
    else if (sliderMode() == Level)
×
1621
    {
1622
        foreach (QSharedPointer<GenericFader> fader, m_fadersMap.values())
×
1623
        {
1624
            if (!fader.isNull())
×
1625
                fader->adjustIntensity(val);
×
1626
        }
1627
    }
1628
}
1629

1630
/*****************************************************************************
1631
 * Load & Save
1632
 *****************************************************************************/
1633

1634
bool VCSlider::loadXML(QXmlStreamReader &root)
1✔
1635
{
1636
    bool visible = false;
1✔
1637
    int x = 0;
1✔
1638
    int y = 0;
1✔
1639
    int w = 0;
1✔
1640
    int h = 0;
1✔
1641

1642
    SliderMode sliderMode = Playback;
1643
    QString str;
1644

1645
    if (root.name() != KXMLQLCVCSlider)
2✔
1646
    {
1647
        qWarning() << Q_FUNC_INFO << "Slider node not found";
×
1648
        return false;
×
1649
    }
1650

1651
    /* Widget commons */
1652
    loadXMLCommon(root);
1✔
1653

1654
    QXmlStreamAttributes attrs = root.attributes();
1✔
1655

1656
    /* Widget style */
1657
    if (attrs.hasAttribute(KXMLQLCVCSliderWidgetStyle))
1✔
1658
        setWidgetStyle(stringToWidgetStyle(attrs.value(KXMLQLCVCSliderWidgetStyle).toString()));
×
1659

1660
    if (attrs.value(KXMLQLCVCSliderInvertedAppearance).toString() == "false")
1✔
1661
        setInvertedAppearance(false);
×
1662
    else
1663
        setInvertedAppearance(true);
1✔
1664

1665
    /* Values catching */
1666
    if (attrs.hasAttribute(KXMLQLCVCSliderCatchValues))
1✔
1667
        setCatchValues(true);
×
1668

1669
    /* Children */
1670
    while (root.readNextStartElement())
1✔
1671
    {
1672
        //qDebug() << "VC Slider tag:" << root.name();
1673
        if (root.name() == KXMLQLCWindowState)
×
1674
        {
1675
            loadXMLWindowState(root, &x, &y, &w, &h, &visible);
×
1676
            setGeometry(x, y, w, h);
×
1677
        }
1678
        else if (root.name() == KXMLQLCVCWidgetAppearance)
×
1679
        {
1680
            loadXMLAppearance(root);
×
1681
        }
1682
        else if (root.name() == KXMLQLCVCSliderMode)
×
1683
        {
1684
            QXmlStreamAttributes mAttrs = root.attributes();
×
1685
            sliderMode = stringToSliderMode(root.readElementText());
×
1686

1687
            str = mAttrs.value(KXMLQLCVCSliderValueDisplayStyle).toString();
×
1688
            setValueDisplayStyle(stringToValueDisplayStyle(str));
×
1689

1690
            if (mAttrs.hasAttribute(KXMLQLCVCSliderClickAndGoType))
×
1691
            {
1692
                str = mAttrs.value(KXMLQLCVCSliderClickAndGoType).toString();
×
1693
                setClickAndGoType(ClickAndGoWidget::stringToClickAndGoType(str));
×
1694
            }
1695

1696
            if (mAttrs.hasAttribute(KXMLQLCVCSliderLevelMonitor))
×
1697
            {
1698
                if (mAttrs.value(KXMLQLCVCSliderLevelMonitor).toString() == "false")
×
1699
                    setChannelsMonitorEnabled(false);
×
1700
                else
1701
                    setChannelsMonitorEnabled(true);
×
1702
            }
1703
        }
1704
        else if (root.name() == KXMLQLCVCSliderOverrideReset)
×
1705
        {
1706
            QString str = loadXMLSources(root, overrideResetInputSourceId);
×
1707
            if (str.isEmpty() == false)
×
1708
                m_overrideResetKeySequence = stripKeySequence(QKeySequence(str));
×
1709
        }
×
1710
        else if (root.name() == KXMLQLCVCSliderLevel)
×
1711
        {
1712
            loadXMLLevel(root);
×
1713
        }
1714
        else if (root.name() == KXMLQLCVCWidgetInput)
×
1715
        {
1716
            loadXMLInput(root);
×
1717
        }
1718
        else if (root.name() == KXMLQLCVCSliderPlayback)
×
1719
        {
1720
            loadXMLPlayback(root);
×
1721
        }
1722
        else
1723
        {
1724
            qWarning() << Q_FUNC_INFO << "Unknown slider tag:" << root.name().toString();
×
1725
            root.skipCurrentElement();
×
1726
        }
1727
    }
1728

1729
    /* Set the mode last, after everything else has been set */
1730
    setSliderMode(sliderMode);
1✔
1731

1732
    return true;
1733
}
1✔
1734

1735
bool VCSlider::loadXMLLevel(QXmlStreamReader &level_root)
×
1736
{
1737
    QString str;
1738

1739
    if (level_root.name() != KXMLQLCVCSliderLevel)
×
1740
    {
1741
        qWarning() << Q_FUNC_INFO << "Slider level node not found";
×
1742
        return false;
×
1743
    }
1744

1745
    QXmlStreamAttributes attrs = level_root.attributes();
×
1746

1747
    /* Level low limit */
1748
    str = attrs.value(KXMLQLCVCSliderLevelLowLimit).toString();
×
1749
    setLevelLowLimit(str.toInt());
×
1750

1751
    /* Level high limit */
1752
    str = attrs.value(KXMLQLCVCSliderLevelHighLimit).toString();
×
1753
    setLevelHighLimit(str.toInt());
×
1754

1755
    /* Level value */
1756
    str = attrs.value(KXMLQLCVCSliderLevelValue).toString();
×
1757
    setLevelValue(str.toInt());
×
1758

1759
    QXmlStreamReader::TokenType tType = level_root.readNext();
×
1760

1761
    if (tType == QXmlStreamReader::EndElement)
×
1762
    {
1763
        level_root.readNext();
×
1764
        return true;
1765
    }
1766

1767
    if (tType == QXmlStreamReader::Characters)
×
1768
        tType = level_root.readNext();
×
1769

1770
    // check if there is a Channel tag defined
1771
    if (tType == QXmlStreamReader::StartElement)
×
1772
    {
1773
        /* Children */
1774
        do
1775
        {
1776
            if (level_root.name() == KXMLQLCVCSliderChannel)
×
1777
            {
1778
                /* Fixture & channel */
1779
                str = level_root.attributes().value(KXMLQLCVCSliderChannelFixture).toString();
×
1780
                addLevelChannel(
×
1781
                    static_cast<quint32>(str.toInt()),
×
1782
                    static_cast<quint32> (level_root.readElementText().toInt()));
×
1783
            }
1784
            else
1785
            {
1786
                qWarning() << Q_FUNC_INFO << "Unknown slider level tag:" << level_root.name().toString();
×
1787
                level_root.skipCurrentElement();
×
1788
            }
1789
        } while (level_root.readNextStartElement());
×
1790
    }
1791

1792
    return true;
1793
}
×
1794

1795
bool VCSlider::loadXMLPlayback(QXmlStreamReader &pb_root)
×
1796
{
1797
    if (pb_root.name() != KXMLQLCVCSliderPlayback)
×
1798
    {
1799
        qWarning() << Q_FUNC_INFO << "Slider playback node not found";
×
1800
        return false;
×
1801
    }
1802

1803
    /* Children */
1804
    while (pb_root.readNextStartElement())
×
1805
    {
1806
        if (pb_root.name() == KXMLQLCVCSliderPlaybackFunction)
×
1807
        {
1808
            /* Function */
1809
            setPlaybackFunction(pb_root.readElementText().toUInt());
×
1810
        }
1811
        else if (pb_root.name() == KXMLQLCVCSliderPlaybackFlash)
×
1812
        {
1813
            setPlaybackFlashEnable(true);
×
1814
            QString str = loadXMLSources(pb_root, flashButtonInputSourceId);
×
1815
            if (str.isEmpty() == false)
×
1816
                m_playbackFlashKeySequence = stripKeySequence(QKeySequence(str));
×
1817
        }
×
1818
        else
1819
        {
1820
            qWarning() << Q_FUNC_INFO << "Unknown slider playback tag:" << pb_root.name().toString();
×
1821
            pb_root.skipCurrentElement();
×
1822
        }
1823
    }
1824

1825
    return true;
1826
}
1827

1828
bool VCSlider::saveXML(QXmlStreamWriter *doc)
×
1829
{
1830
    QString str;
1831

1832
    Q_ASSERT(doc != NULL);
1833

1834
    /* VC Slider entry */
1835
    doc->writeStartElement(KXMLQLCVCSlider);
×
1836

1837
    saveXMLCommon(doc);
×
1838

1839
    /* Widget style */
1840
    doc->writeAttribute(KXMLQLCVCSliderWidgetStyle, widgetStyleToString(widgetStyle()));
×
1841

1842
    /* Inverted appearance */
1843
    if (invertedAppearance() == true)
×
1844
        doc->writeAttribute(KXMLQLCVCSliderInvertedAppearance, "true");
×
1845
    else
1846
        doc->writeAttribute(KXMLQLCVCSliderInvertedAppearance, "false");
×
1847

1848
    /* Values catching */
1849
    if (catchValues() == true)
×
1850
        doc->writeAttribute(KXMLQLCVCSliderCatchValues, "true");
×
1851

1852
    /* Window state */
1853
    saveXMLWindowState(doc);
×
1854

1855
    /* Appearance */
1856
    saveXMLAppearance(doc);
×
1857

1858
    /* External input */
1859
    saveXMLInput(doc, inputSource(sliderInputSourceId));
×
1860

1861
    /* SliderMode */
1862
    doc->writeStartElement(KXMLQLCVCSliderMode);
×
1863

1864
    /* Value display style */
1865
    str = valueDisplayStyleToString(valueDisplayStyle());
×
1866
    doc->writeAttribute(KXMLQLCVCSliderValueDisplayStyle, str);
×
1867

1868
    /* Click And Go type */
1869
    str = ClickAndGoWidget::clickAndGoTypeToString(m_cngType);
×
1870
    doc->writeAttribute(KXMLQLCVCSliderClickAndGoType, str);
×
1871

1872
    /* Monitor channels */
1873
    if (sliderMode() == Level)
×
1874
    {
1875
        if (channelsMonitorEnabled() == true)
×
1876
            doc->writeAttribute(KXMLQLCVCSliderLevelMonitor, "true");
×
1877
        else
1878
            doc->writeAttribute(KXMLQLCVCSliderLevelMonitor, "false");
×
1879
    }
1880

1881
    doc->writeCharacters(sliderModeToString(m_sliderMode));
×
1882

1883
    /* End the <SliderMode> tag */
1884
    doc->writeEndElement();
×
1885

1886
    if (sliderMode() == Level && channelsMonitorEnabled() == true)
×
1887
    {
1888
        doc->writeStartElement(KXMLQLCVCSliderOverrideReset);
×
1889
        if (m_overrideResetKeySequence.toString().isEmpty() == false)
×
1890
            doc->writeTextElement(KXMLQLCVCWidgetKey, m_overrideResetKeySequence.toString());
×
1891
        saveXMLInput(doc, inputSource(overrideResetInputSourceId));
×
1892
        doc->writeEndElement();
×
1893
    }
1894

1895
    /* Level */
1896
    doc->writeStartElement(KXMLQLCVCSliderLevel);
×
1897
    /* Level low limit */
1898
    doc->writeAttribute(KXMLQLCVCSliderLevelLowLimit, QString::number(levelLowLimit()));
×
1899
    /* Level high limit */
1900
    doc->writeAttribute(KXMLQLCVCSliderLevelHighLimit, QString::number(levelHighLimit()));
×
1901
    /* Level value */
1902
    doc->writeAttribute(KXMLQLCVCSliderLevelValue, QString::number(levelValue()));
×
1903

1904
    /* Level channels */
1905
    QListIterator <LevelChannel> it(m_levelChannels);
×
1906
    while (it.hasNext() == true)
×
1907
    {
1908
        LevelChannel lch(it.next());
×
1909
        lch.saveXML(doc);
×
1910
    }
1911

1912
    /* End the <Level> tag */
1913
    doc->writeEndElement();
×
1914

1915
    /* Playback */
1916
    doc->writeStartElement(KXMLQLCVCSliderPlayback);
×
1917
    /* Playback function */
1918
    doc->writeTextElement(KXMLQLCVCSliderPlaybackFunction, QString::number(playbackFunction()));
×
1919

1920
    if (sliderMode() == Playback && playbackFlashEnable() == true)
×
1921
    {
1922
        doc->writeStartElement(KXMLQLCVCSliderPlaybackFlash);
×
1923
        if (m_playbackFlashKeySequence.toString().isEmpty() == false)
×
1924
            doc->writeTextElement(KXMLQLCVCWidgetKey, m_playbackFlashKeySequence.toString());
×
1925
        saveXMLInput(doc, inputSource(flashButtonInputSourceId));
×
1926
        doc->writeEndElement();
×
1927
    }
1928

1929
    /* End the <Playback> tag */
1930
    doc->writeEndElement();
×
1931

1932
    /* End the <Slider> tag */
1933
    doc->writeEndElement();
×
1934

1935
    return true;
×
1936
}
×
1937

1938
/****************************************************************************
1939
 * LevelChannel implementation
1940
 ****************************************************************************/
1941

1942
VCSlider::LevelChannel::LevelChannel(quint32 fid, quint32 ch)
×
1943
{
1944
    this->fixture = fid;
×
1945
    this->channel = ch;
×
1946
}
×
1947

1948
VCSlider::LevelChannel::LevelChannel(const LevelChannel& lc)
×
1949
{
1950
    *this = lc;
×
1951
}
×
1952

1953
VCSlider::LevelChannel &VCSlider::LevelChannel::operator=(const VCSlider::LevelChannel &lc)
×
1954
{
1955
    if (this != &lc)
×
1956
    {
1957
        this->fixture = lc.fixture;
×
1958
        this->channel = lc.channel;
×
1959
    }
1960

1961
    return *this;
×
1962
}
1963

1964
bool VCSlider::LevelChannel::operator==(const LevelChannel& lc) const
×
1965
{
1966
    return (this->fixture == lc.fixture && this->channel == lc.channel);
×
1967
}
1968

1969
bool VCSlider::LevelChannel::operator<(const LevelChannel& lc) const
×
1970
{
1971
    if (this->fixture < lc.fixture)
×
1972
        return true;
1973
    else if (this->fixture == lc.fixture && this->channel < lc.channel)
×
1974
        return true;
1975
    else
1976
        return false;
×
1977
}
1978

1979
void VCSlider::LevelChannel::saveXML(QXmlStreamWriter *doc) const
×
1980
{
1981
    Q_ASSERT(doc != NULL);
1982

1983
    doc->writeStartElement(KXMLQLCVCSliderChannel);
×
1984

1985
    doc->writeAttribute(KXMLQLCVCSliderChannelFixture,
×
1986
                       QString::number(this->fixture));
×
1987

1988
    doc->writeCharacters(QString::number(this->channel));
×
1989
    doc->writeEndElement();
×
1990
}
×
1991

1992
void VCSlider::FlashButton::mousePressEvent(QMouseEvent *e)
×
1993
{
1994
    QToolButton::mousePressEvent(e);
×
1995
    // ignore event so that it can be
1996
    // forwarded to parent widget
1997
    e->ignore();
1998
}
×
1999

2000
void VCSlider::FlashButton::mouseReleaseEvent(QMouseEvent *e)
×
2001
{
2002
    QToolButton::mouseReleaseEvent(e);
×
2003
    // ignore event so that it can be
2004
    // forwarded to parent widget
2005
    e->ignore();
2006
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc