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

mcallegari / qlcplus / 4811315907

pending completion
4811315907

push

github

Massimo Callegari
qmlui: fix simple desk out of bounds channels

5 of 5 new or added lines in 1 file covered. (100.0%)

15287 of 54433 relevant lines covered (28.08%)

20270.74 hits per line

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

79.84
/engine/src/keypadparser.cpp
1
/*
2
  Q Light Controller Plus
3
  keypadparser.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 <cmath>
21

22
#include "keypadparser.h"
23
#include "qlcmacros.h"
24
#include "universe.h"
25

26
KeyPadParser::KeyPadParser()
1✔
27
{
28

29
}
1✔
30

31
QList<SceneValue> KeyPadParser::parseCommand(Doc *doc, QString command,
12✔
32
                                             QByteArray &uniData)
33
{
34
    QList<SceneValue> values;
12✔
35
    if (doc == NULL)
12✔
36
        return values;
×
37

38
    QStringList tokens = command.split(" ");
24✔
39

40
    int lastCommand = CommandNone;
12✔
41
    quint32 fromChannel = 0;
12✔
42
    quint32 toChannel = 0;
12✔
43
    quint32 byChannel = 1;
12✔
44
    bool channelSet = false;
12✔
45
    float fromValue = 0;
12✔
46
    float toValue = 0;
12✔
47
    int thruCount = 0;
12✔
48

49
    foreach (QString token, tokens)
112✔
50
    {
51
        if (token.isEmpty())
50✔
52
            continue;
×
53

54
        if (token == "AT")
50✔
55
        {
56
            lastCommand = CommandAT;
7✔
57
        }
58
        else if (token == "THRU")
43✔
59
        {
60
            lastCommand = CommandTHRU;
7✔
61
        }
62
        else if (token == "FULL")
36✔
63
        {
64
            if (lastCommand == CommandAT)
3✔
65
                toValue = 255;
1✔
66

67
            lastCommand = CommandFULL;
3✔
68
        }
69
        else if (token == "ZERO")
33✔
70
        {
71
            if (lastCommand == CommandAT)
2✔
72
                toValue = 0;
1✔
73

74
            lastCommand = CommandZERO;
2✔
75
        }
76
        else if (token == "BY")
31✔
77
        {
78
            lastCommand = CommandBY;
3✔
79
        }
80
        else if (token == "+")
28✔
81
        {
82
            lastCommand = CommandPlus;
×
83
        }
84
        else if (token == "-")
28✔
85
        {
86
            lastCommand = CommandMinus;
×
87
        }
88
        else if (token == "+%")
28✔
89
        {
90
            lastCommand = CommandPlusPercent;
1✔
91
        }
92

93
        else if (token == "-%")
27✔
94
        {
95
            lastCommand = CommandMinusPercent;
1✔
96
        }
97
        else if (token == "%")
26✔
98
        {
99
            if (lastCommand == CommandPlus)
×
100
                lastCommand = CommandPlusPercent;
×
101
            else if (lastCommand == CommandMinus)
×
102
                lastCommand = CommandMinusPercent;
×
103
        }
104
        else
105
        {
106
            // most likely a number
107
            bool ok = false;
26✔
108
            int number = token.toUInt(&ok);
26✔
109

110
            if (ok == false)
26✔
111
                continue;
×
112

113
            switch (lastCommand)
26✔
114
            {
115
                case CommandNone:
9✔
116
                    // no command: this is a channel number
117
                    if (number <= 0)
9✔
118
                        break;
×
119

120
                    fromChannel = number;
9✔
121
                    toChannel = fromChannel;
9✔
122
                    channelSet = true;
9✔
123
                break;
9✔
124
                case CommandAT:
5✔
125
                    fromValue = float(number);
5✔
126
                    toValue = fromValue;
5✔
127
                break;
5✔
128
                case CommandTHRU:
7✔
129
                    if (thruCount == 0)
7✔
130
                        toChannel = number;
6✔
131
                    else
132
                        toValue = float(number);
1✔
133
                    thruCount++;
7✔
134
                break;
7✔
135
                case CommandFULL:
×
136
                    fromValue = 255;
×
137
                    toValue = 255;
×
138
                break;
×
139
                case CommandZERO:
×
140
                    fromValue = 0;
×
141
                    toValue = 0;
×
142
                break;
×
143
                case CommandBY:
3✔
144
                    byChannel = number;
3✔
145
                break;
3✔
146
                case CommandPlus:
×
147
                case CommandMinus:
148
                    toValue = number;
×
149
                break;
×
150
                case CommandPlusPercent:
2✔
151
                case CommandMinusPercent:
152
                    toValue = float(number) / 100.0;
2✔
153
                break;
2✔
154
            }
155
        }
156
    }
157

158
    /** handle the case where channel(s) are not specified.
159
     *  Compose a list of values based on the last channel list */
160

161
    if (channelSet == false)
12✔
162
    {
163
        if (m_channels.isEmpty())
3✔
164
            return values;
×
165

166
        for (int i = 0; i < m_channels.count(); i++)
27✔
167
        {
168
            SceneValue scv;
48✔
169

170
            scv.channel = m_channels.at(i);
24✔
171
            scv.value = toValue;
24✔
172
            values.append(scv);
24✔
173
        }
174

175
        return values;
3✔
176
    }
177
    else
178
    {
179
        m_channels.clear();
9✔
180
    }
181

182
    float valueDelta = 0;
9✔
183
    if (toValue != fromValue)
9✔
184
    {
185
        valueDelta = (float(toChannel) - float(fromChannel)) / float(byChannel);
3✔
186
        valueDelta = (float(toValue) - float(fromValue)) / valueDelta;
3✔
187
    }
188

189
    for (quint32 i = fromChannel - 1; i <= toChannel - 1; i += byChannel)
61✔
190
    {
191
        uchar uniValue = 0;
52✔
192
        SceneValue scv;
52✔
193

194
        if (i >= UNIVERSE_SIZE)
52✔
195
            continue;
×
196

197
        if (quint32(uniData.length()) > i)
52✔
198
            uniValue = uchar(uniData.at(i));
52✔
199

200
        scv.channel = i;
52✔
201
        if (lastCommand == CommandPlus)
52✔
202
            scv.value = CLAMP(uniValue + toValue, 0, 255);
×
203
        else if (lastCommand == CommandMinus)
52✔
204
            scv.value = CLAMP(uniValue - toValue, 0, 255);
×
205
        else if (lastCommand == CommandPlusPercent)
52✔
206
            scv.value = CLAMP(lrintf(uniValue * (1.0 + toValue)), 0, 255);
6✔
207
        else if (lastCommand == CommandMinusPercent)
46✔
208
            scv.value = CLAMP(lrintf(uniValue - (float(uniValue) * toValue)), 0, 255);
6✔
209
        else if (lastCommand == CommandZERO)
40✔
210
            scv.value = 0;
1✔
211
        else if (lastCommand == CommandFULL)
39✔
212
            scv.value = 255;
11✔
213
        else
214
            scv.value = uchar(fromValue);
28✔
215

216
        if (m_channels.contains(scv.channel) == false)
52✔
217
            m_channels.append(scv.channel);
52✔
218

219
        values.append(scv);
52✔
220
        fromValue += valueDelta;
52✔
221
    }
222

223
    return values;
9✔
224
}
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