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

mcallegari / qlcplus / 16884422552

11 Aug 2025 03:21PM UTC coverage: 34.258% (-0.03%) from 34.289%
16884422552

Pull #1789

github

web-flow
Merge 311199581 into 7cc853cc5
Pull Request #1789: #1786 sync virtual console button colour to RGB button custom feedback

22 of 111 new or added lines in 7 files covered. (19.82%)

3 existing lines in 2 files now uncovered.

17722 of 51731 relevant lines covered (34.26%)

19401.42 hits per line

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

32.5
/ui/src/inputselectionwidget.cpp
1
/*
2
  Q Light Controller Plus
3
  inputselectionwidget.cpp
4

5
  Copyright (c) Massimo Callegari
6

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

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

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

20
#include <QDebug>
21
#include <qmath.h>
22

23
#include "customfeedbackdialog.h"
24
#include "inputselectionwidget.h"
25
#include "selectinputchannel.h"
26
#include "qlcinputchannel.h"
27
#include "assignhotkey.h"
28
#include "inputpatch.h"
29
#include "doc.h"
30

31
InputSelectionWidget::InputSelectionWidget(Doc *doc, QWidget *parent)
4✔
32
    : QWidget(parent)
33
    , m_doc(doc)
4✔
34
    , m_widgetPage(0)
4✔
35
    , m_emitOdd(false)
4✔
36
    , m_supportMonitoring(false)
4✔
37
    , m_signalsReceived(0)
4✔
38
{
39
    Q_ASSERT(doc != NULL);
4✔
40

41
    setupUi(this);
4✔
42

43
    m_customFbButton->setVisible(false);
4✔
44

45
    connect(m_attachKey, SIGNAL(clicked()), this, SLOT(slotAttachKey()));
4✔
46
    connect(m_detachKey, SIGNAL(clicked()), this, SLOT(slotDetachKey()));
4✔
47

48
    connect(m_autoDetectInputButton, SIGNAL(toggled(bool)),
4✔
49
            this, SLOT(slotAutoDetectInputToggled(bool)));
50
    connect(m_chooseInputButton, SIGNAL(clicked()),
4✔
51
            this, SLOT(slotChooseInputClicked()));
52

53
    connect(m_customFbButton, SIGNAL(clicked(bool)),
4✔
54
            this, SLOT(slotCustomFeedbackClicked()));
55

56
    connect(m_syncColour, SIGNAL(clicked(bool)),
4✔
57
            this, SLOT(slotSyncStatusChanged()));
58
}
4✔
59

60
InputSelectionWidget::~InputSelectionWidget()
8✔
61
{
62
}
8✔
63

64
void InputSelectionWidget::setKeyInputVisibility(bool visible)
×
65
{
66
    m_keyInputGroup->setVisible(visible);
×
67
}
×
68

69
void InputSelectionWidget::setCustomFeedbackVisibility(bool visible)
4✔
70
{
71
    m_customFbButton->setVisible(visible);
4✔
72
}
4✔
73

74
void InputSelectionWidget::setMonitoringSupport(bool enable)
×
75
{
76
    m_supportMonitoring = enable;
×
77
}
×
78

79
void InputSelectionWidget::setTitle(QString title)
3✔
80
{
81
    m_extInputGroup->setTitle(title);
3✔
82
}
3✔
83

84
void InputSelectionWidget::setWidgetPage(int page)
4✔
85
{
86
    m_widgetPage = page;
4✔
87
}
4✔
88

89
bool InputSelectionWidget::isAutoDetecting()
×
90
{
91
   return m_autoDetectInputButton->isChecked();
×
92
}
93

94
void InputSelectionWidget::stopAutoDetection()
×
95
{
96
    if (m_autoDetectInputButton->isChecked())
×
97
        m_autoDetectInputButton->toggle();
×
98
}
×
99

100
void InputSelectionWidget::emitOddValues(bool enable)
×
101
{
102
    m_emitOdd = enable;
×
103
}
×
104

105
void InputSelectionWidget::setKeySequence(const QKeySequence &keySequence)
3✔
106
{
107
    m_keySequence = QKeySequence(keySequence);
3✔
108
    m_keyEdit->setText(m_keySequence.toString(QKeySequence::NativeText));
3✔
109
}
3✔
110

111
QKeySequence InputSelectionWidget::keySequence() const
3✔
112
{
113
    return m_keySequence;
3✔
114
}
115

116
void InputSelectionWidget::setInputSource(const QSharedPointer<QLCInputSource> &source)
3✔
117
{
118
    m_inputSource = source;
3✔
119
    updateInputSource();
3✔
120
}
3✔
121

122
QSharedPointer<QLCInputSource> InputSelectionWidget::inputSource() const
3✔
123
{
124
    return m_inputSource;
3✔
125
}
126

127
void InputSelectionWidget::updateFeedback()
3✔
128
{
129
    if (m_inputSource.isNull())
3✔
130
        return;
3✔
131

NEW
132
    InputPatch *ip = m_doc->inputOutputMap()->inputPatch(m_inputSource->universe());
×
NEW
133
    if (ip != NULL && ip->profile() != NULL)
×
134
    {
NEW
135
        QLCInputProfile *m_profile = ip->profile();
×
136

NEW
137
        if (m_profile->hasColorTable())
×
138
        {
NEW
139
            QMapIterator <uchar, QPair<QString, QColor>> it(m_profile->colorTable());
×
140

NEW
141
            int currentDistanceWithRed = 255 * 255 * 3;
×
NEW
142
            int currentDistanceWithGreen = 255 * 255 * 3;
×
NEW
143
            int currentDistanceWithYellow = 255 * 255 * 3;
×
144

NEW
145
            uchar redValue = 0;
×
NEW
146
            uchar greenValue = 0;
×
NEW
147
            uchar yellowValue = 0;
×
NEW
148
            while (it.hasNext() == true)
×
149
            {
NEW
150
                it.next();
×
NEW
151
                QPair<QString, QColor> lc = it.value();
×
NEW
152
                QColor colorValue = lc.second;
×
NEW
153
                int distanceWithRed = getColorDistance(colorValue, QColor(Qt::red));
×
NEW
154
                int distanceWithGreen = getColorDistance(colorValue, QColor(Qt::green));
×
NEW
155
                int distanceWithYellow = getColorDistance(colorValue, QColor(Qt::yellow));
×
NEW
156
                if (distanceWithRed < currentDistanceWithRed)
×
157
                {
NEW
158
                    currentDistanceWithRed = distanceWithRed;
×
NEW
159
                    redValue = it.key();
×
160
                }
NEW
161
                if (distanceWithGreen < currentDistanceWithGreen)
×
162
                {
NEW
163
                    currentDistanceWithGreen = distanceWithGreen;
×
NEW
164
                    greenValue = it.key();
×
165
                }
NEW
166
                if (distanceWithYellow < currentDistanceWithYellow)
×
167
                {
NEW
168
                    currentDistanceWithYellow = distanceWithYellow;
×
NEW
169
                    yellowValue = it.key();
×
170
                }
NEW
171
            }
×
NEW
172
            m_inputSource->setFeedbackValue(QLCInputFeedback::LowerValue, redValue);
×
NEW
173
            m_inputSource->setFeedbackValue(QLCInputFeedback::UpperValue, greenValue);
×
NEW
174
            m_inputSource->setFeedbackValue(QLCInputFeedback::MonitorValue, yellowValue);
×
NEW
175
        }
×
176

NEW
177
        QLCInputChannel *m_channel = m_profile->channel(m_inputSource->channel());
×
NEW
178
        if (isSyncColor() && m_channel != NULL)
×
179
        {
NEW
180
            if (m_channel->lowerValue() > 0)
×
181
            {
NEW
182
                if (m_channel->lowerValue() == UCHAR_MAX)
×
NEW
183
                    m_inputSource->setFeedbackValue(QLCInputFeedback::LowerValue, UCHAR_MAX);
×
184
                else
NEW
185
                    m_inputSource->setFeedbackValue(QLCInputFeedback::LowerValue, (m_channel->lowerValue() + 1) / 2 * 2);
×
186
            }
187

NEW
188
            if (m_channel->upperValue() > 0)
×
189
            {
NEW
190
                if (m_channel->upperValue() == UCHAR_MAX)
×
NEW
191
                    m_inputSource->setFeedbackValue(QLCInputFeedback::UpperValue, UCHAR_MAX);
×
192
                else
NEW
193
                    m_inputSource->setFeedbackValue(QLCInputFeedback::UpperValue, (m_channel->upperValue() + 1) / 2 * 2);
×
194
            }
195
        }
196
    }
197
}
198

NEW
199
int InputSelectionWidget::getColorDistance(const QColor &color1, const QColor &color2)
×
200
{
NEW
201
    return qSqrt(qPow(color1.red() - color2.red(), 2) +
×
NEW
202
                 qPow(color1.green() - color2.green(), 2) +
×
NEW
203
                 qPow(color1.blue() - color2.blue(), 2));
×
204
}
205

NEW
206
void InputSelectionWidget::slotSyncStatusChanged()
×
207
{
NEW
208
    updateFeedback();
×
NEW
209
}
×
210

UNCOV
211
void InputSelectionWidget::slotAttachKey()
×
212
{
213
    AssignHotKey ahk(this, m_keySequence);
×
214
    if (ahk.exec() == QDialog::Accepted)
×
215
    {
216
        setKeySequence(QKeySequence(ahk.keySequence()));
×
217
        emit keySequenceChanged(m_keySequence);
×
218
    }
219
}
×
220

221
void InputSelectionWidget::slotDetachKey()
×
222
{
223
    setKeySequence(QKeySequence());
×
224
    emit keySequenceChanged(m_keySequence);
×
225
}
×
226

227
void InputSelectionWidget::slotAutoDetectInputToggled(bool checked)
×
228
{
229
    if (checked == true)
×
230
    {
231
        connect(m_doc->inputOutputMap(),
×
232
                SIGNAL(inputValueChanged(quint32,quint32,uchar)),
233
                this, SLOT(slotInputValueChanged(quint32,quint32)));
234
    }
235
    else
236
    {
237
        disconnect(m_doc->inputOutputMap(),
×
238
                   SIGNAL(inputValueChanged(quint32,quint32,uchar)),
239
                   this, SLOT(slotInputValueChanged(quint32,quint32)));
240
    }
241
    emit autoDetectToggled(checked);
×
242
}
×
243

244
void InputSelectionWidget::slotInputValueChanged(quint32 universe, quint32 channel)
×
245
{
246
    if (m_emitOdd == true && m_signalsReceived % 2)
×
247
    {
248
        emit inputValueChanged(universe, (m_widgetPage << 16) | channel);
×
249
        m_signalsReceived++;
×
250
        return;
×
251
    }
252

253
    m_inputSource = QSharedPointer<QLCInputSource>(new QLCInputSource(universe, (m_widgetPage << 16) | channel));
×
254
    updateInputSource();
×
255
    m_signalsReceived++;
×
256

257
    if (m_emitOdd == false)
×
258
        emit inputValueChanged(universe, (m_widgetPage << 16) | channel);
×
259
}
260

261
void InputSelectionWidget::slotChooseInputClicked()
×
262
{
263
    SelectInputChannel sic(this, m_doc->inputOutputMap());
×
264
    if (sic.exec() == QDialog::Accepted)
×
265
    {
266
        m_inputSource = QSharedPointer<QLCInputSource>(new QLCInputSource(sic.universe(), (m_widgetPage << 16) | sic.channel()));
×
267
        updateInputSource();
×
268
        emit inputValueChanged(sic.universe(), (m_widgetPage << 16) | sic.channel());
×
269
    }
270
}
×
271

272
void InputSelectionWidget::slotCustomFeedbackClicked()
×
273
{
274
    CustomFeedbackDialog cfDialog(m_doc, m_inputSource, this);
×
275
    cfDialog.setMonitoringVisibility(m_supportMonitoring);
×
NEW
276
    cfDialog.setSyncStatus(m_syncColour->isChecked());
×
277
    cfDialog.exec();
×
278
}
×
279

280
void InputSelectionWidget::updateInputSource()
3✔
281
{
282
    QString uniName;
3✔
283
    QString chName;
3✔
284

285
    if (!m_inputSource || m_doc->inputOutputMap()->inputSourceNames(m_inputSource, uniName, chName) == false)
3✔
286
    {
287
        uniName = KInputNone;
3✔
288
        chName = KInputNone;
3✔
289
    }
290

291
    m_inputUniverseEdit->setText(uniName);
3✔
292
    m_inputChannelEdit->setText(chName);
3✔
293
    updateFeedback();
3✔
294
}
3✔
295

NEW
296
bool InputSelectionWidget::isSyncColor()
×
297
{
NEW
298
    return m_syncColour->isChecked();
×
299
}
300

NEW
301
void InputSelectionWidget::setSyncStatus(bool enable)
×
302
{
NEW
303
    m_syncColour->setChecked(enable);
×
UNCOV
304
}
×
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