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

mcallegari / qlcplus / 21760395819

06 Feb 2026 05:52PM UTC coverage: 33.994% (-0.08%) from 34.078%
21760395819

push

github

mcallegari
Back to 5.2.1 debug

17635 of 51877 relevant lines covered (33.99%)

19809.79 hits per line

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

82.39
/engine/src/channelsgroup.cpp
1
/*
2
  Q Light Controller
3
  channelsgroup.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 <QXmlStreamReader>
21
#include <QXmlStreamWriter>
22
#include <QDebug>
23

24
#include "qlcfixturemode.h"
25
#include "channelsgroup.h"
26
#include "scenevalue.h"
27
#include "fixture.h"
28
#include "doc.h"
29

30
#define KXMLQLCChannelsGroupID    QStringLiteral("ID")
31
#define KXMLQLCChannelsGroupName  QStringLiteral("Name")
32
#define KXMLQLCChannelsGroupValue QStringLiteral("Value")
33

34
#define KXMLQLCChannelsGroupInputUniverse QStringLiteral("InputUniverse")
35
#define KXMLQLCChannelsGroupInputChannel  QStringLiteral("InputChannel")
36

37

38
ChannelsGroup::ChannelsGroup(Doc* doc)
13✔
39
    : QObject(doc)
40
    , m_doc(doc)
13✔
41
    , m_id(ChannelsGroup::invalidId())
26✔
42
    , m_masterValue(0)
13✔
43
{
44
    setName(tr("New Group"));
13✔
45

46
    init();
13✔
47
}
13✔
48

49
ChannelsGroup::ChannelsGroup(Doc* doc, const ChannelsGroup* chg)
×
50
    : QObject(doc)
51
    , m_doc(doc)
×
52
    , m_id(chg->id())
×
53
    , m_name(chg->name())
×
54
    , m_masterValue(0)
×
55
    , m_channels(chg->getChannels())
×
56
    , m_input(chg->inputSource())
×
57
{
58
    init();
×
59
}
×
60

61
ChannelsGroup::~ChannelsGroup()
18✔
62
{
63
}
18✔
64

65
void ChannelsGroup::init()
13✔
66
{
67
    connect(m_doc, SIGNAL(fixtureRemoved(quint32)),
13✔
68
            this, SLOT(slotFixtureRemoved(quint32)));
69
}
13✔
70

71
void ChannelsGroup::slotFixtureRemoved(quint32 fixtureId)
2✔
72
{
73
    bool hasChanged = false;
2✔
74

75
    QMutableListIterator<SceneValue> channelsIt(m_channels);
2✔
76
    while (channelsIt.hasNext())
6✔
77
    {
78
        SceneValue scv(channelsIt.next());
4✔
79
        if (scv.fxi == fixtureId)
4✔
80
        {
81
            channelsIt.remove();
1✔
82
            hasChanged = true;
1✔
83
        }
84
    }
4✔
85

86
    if (hasChanged)
2✔
87
        emit changed(this->id());
1✔
88
}
2✔
89

90
/****************************************************************************
91
 * ID
92
 ****************************************************************************/
93

94
void ChannelsGroup::setId(quint32 id)
7✔
95
{
96
    m_id = id;
7✔
97
}
7✔
98

99
quint32 ChannelsGroup::id() const
37✔
100
{
101
    return m_id;
37✔
102
}
103

104
quint32 ChannelsGroup::invalidId()
36✔
105
{
106
    return UINT_MAX;
36✔
107
}
108

109
/****************************************************************************
110
 * Name
111
 ****************************************************************************/
112

113
void ChannelsGroup::setName(const QString& name)
15✔
114
{
115
    m_name = name;
15✔
116
    emit changed(this->id());
15✔
117
}
15✔
118

119
QString ChannelsGroup::name() const
5✔
120
{
121
    return m_name;
5✔
122
}
123

124
/************************************************************************
125
 * Channels
126
 ************************************************************************/
127

128
void ChannelsGroup::resetChannels()
×
129
{
130
    m_channels.clear();
×
131
}
×
132

133
bool ChannelsGroup::addChannel(quint32 fxid, quint32 channel)
8✔
134
{
135
    if (fxid == invalidId())
8✔
136
        return false;
1✔
137

138
    m_channels.append(SceneValue(fxid, channel, 0));
7✔
139

140
    return true;
7✔
141
}
142

143

144
QList <SceneValue> ChannelsGroup::getChannels() const
11✔
145
{
146
    return m_channels;
11✔
147
}
148

149
/*********************************************************************
150
 * External input
151
 *********************************************************************/
152
void ChannelsGroup::setInputSource(QSharedPointer<QLCInputSource> const& source)
3✔
153
{
154
    if (!m_input.isNull() && m_input->isValid())
3✔
155
        disconnect(m_doc->inputOutputMap(), SIGNAL(inputValueChanged(quint32,quint32,uchar)),
×
156
                this, SLOT(slotInputValueChanged(quint32,quint32,uchar)));
157

158
    m_input = source;
3✔
159

160
    // Connect when the first valid input source is set
161
    if (!source.isNull() && source->isValid())
3✔
162
        connect(m_doc->inputOutputMap(), SIGNAL(inputValueChanged(quint32,quint32,uchar)),
3✔
163
                this, SLOT(slotInputValueChanged(quint32,quint32,uchar)));
164
}
3✔
165

166
QSharedPointer<QLCInputSource> const& ChannelsGroup::inputSource() const
10✔
167
{
168
    return m_input;
10✔
169
}
170

171
void ChannelsGroup::slotInputValueChanged(quint32 universe, quint32 channel, uchar value)
3✔
172
{
173
    Q_UNUSED(value);
174

175
    /* Don't let input data thru in operate mode */
176
    if (m_doc->mode() == Doc::Operate)
3✔
177
        return;
1✔
178

179
    //qDebug() << Q_FUNC_INFO << "universe: " << universe << ", channel: " << channel << ", value: " << value;
180

181
    if (inputSource() != NULL &&
2✔
182
        inputSource()->universe() == universe &&
4✔
183
        inputSource()->channel() == channel)
2✔
184
    {
185
        emit valueChanged(channel, value);
1✔
186
    }
187
}
188

189
/*****************************************************************************
190
 * Load & Save
191
 *****************************************************************************/
192
bool ChannelsGroup::loader(QXmlStreamReader &xmlDoc, Doc* doc)
1✔
193
{
194
    bool result = false;
1✔
195

196
    ChannelsGroup* grp = new ChannelsGroup(doc);
1✔
197
    Q_ASSERT(grp != NULL);
1✔
198

199
    if (grp->loadXML(xmlDoc) == true)
1✔
200
    {
201
        doc->addChannelsGroup(grp, grp->id());
1✔
202
        result = true;
1✔
203
    }
204
    else
205
    {
206
        qWarning() << Q_FUNC_INFO << "ChannelsGroup" << grp->name() << "cannot be loaded.";
×
207
        delete grp;
×
208
        result = false;
×
209
    }
210

211
    return result;
1✔
212
}
213

214
bool ChannelsGroup::saveXML(QXmlStreamWriter *doc)
1✔
215
{
216
    Q_ASSERT(doc != NULL);
1✔
217

218
    QString str;
1✔
219
    foreach (SceneValue value, this->getChannels())
3✔
220
    {
221
        if (str.isEmpty() == false)
1✔
222
            str.append(",");
×
223
        str.append(QString("%1,%2").arg(value.fxi).arg(value.channel));
1✔
224
    }
2✔
225

226
    /* Channels Group entry */
227
    doc->writeStartElement(KXMLQLCChannelsGroup);
2✔
228
    doc->writeAttribute(KXMLQLCChannelsGroupID, QString::number(this->id()));
2✔
229
    doc->writeAttribute(KXMLQLCChannelsGroupName, this->name());
2✔
230
    doc->writeAttribute(KXMLQLCChannelsGroupValue, QString::number(m_masterValue));
2✔
231

232
    if (!m_input.isNull() && m_input->isValid())
1✔
233
    {
234
        doc->writeAttribute(KXMLQLCChannelsGroupInputUniverse,QString("%1").arg(m_input->universe()));
2✔
235
        doc->writeAttribute(KXMLQLCChannelsGroupInputChannel, QString("%1").arg(m_input->channel()));
2✔
236
    }
237
    if (str.isEmpty() == false)
1✔
238
        doc->writeCharacters(str);
1✔
239

240
    doc->writeEndElement();
1✔
241

242
    return true;
1✔
243
}
1✔
244

245
bool ChannelsGroup::loadXML(QXmlStreamReader &xmlDoc)
2✔
246
{
247
    if (xmlDoc.name() != KXMLQLCChannelsGroup)
2✔
248
    {
249
        qWarning() << Q_FUNC_INFO << "Channels group node not found";
×
250
        return false;
×
251
    }
252

253
    QXmlStreamAttributes attrs = xmlDoc.attributes();
2✔
254

255
    bool ok = false;
2✔
256
    quint32 id = attrs.value(KXMLQLCChannelsGroupID).toString().toUInt(&ok);
2✔
257
    if (ok == false)
2✔
258
    {
259
        qWarning() << "Invalid ChannelsGroup ID:" << attrs.value(KXMLQLCChannelsGroupID).toString();
×
260
        return false;
×
261
    }
262

263
    // Assign the ID to myself
264
    m_id = id;
2✔
265

266
    if (attrs.hasAttribute(KXMLQLCChannelsGroupName) == true)
2✔
267
        m_name = attrs.value(KXMLQLCChannelsGroupName).toString();
2✔
268
    if (attrs.hasAttribute(KXMLQLCChannelsGroupValue) == true)
2✔
269
        m_masterValue = uchar(attrs.value(KXMLQLCChannelsGroupValue).toString().toInt());
1✔
270

271
    QString chansValues = xmlDoc.readElementText();
2✔
272
    if (chansValues.isEmpty() == false)
2✔
273
    {
274
        QStringList varray = chansValues.split(",");
2✔
275
        for (int i = 0; i < varray.count(); i+=2)
4✔
276
        {
277
            SceneValue scv(QString(varray.at(i)).toUInt(),
4✔
278
                           QString(varray.at(i + 1)).toUInt(), 0);
4✔
279
            Fixture* fxi = m_doc->fixture(scv.fxi);
2✔
280
            if (fxi == NULL)
2✔
281
            {
282
                qWarning() << Q_FUNC_INFO << "Fixture not present:" << scv.fxi;
×
283
                continue;
×
284
            }
285
            const QLCChannel* ch = fxi->channel(scv.channel);
2✔
286
            if (ch == NULL)
2✔
287
            {
288
                qWarning() << Q_FUNC_INFO << "Fixture" << scv.fxi << "does not have channel" << scv.channel;
×
289
                continue;
×
290
            }
291
            m_channels.append(scv);
2✔
292
        }
2✔
293
    }
2✔
294

295
    if (attrs.hasAttribute(KXMLQLCChannelsGroupInputUniverse) == true &&
7✔
296
        attrs.hasAttribute(KXMLQLCChannelsGroupInputChannel) == true)
3✔
297
    {
298
        quint32 uni = attrs.value(KXMLQLCChannelsGroupInputUniverse).toString().toInt();
1✔
299
        quint32 ch = attrs.value(KXMLQLCChannelsGroupInputChannel).toString().toInt();
1✔
300
        setInputSource(QSharedPointer<QLCInputSource>(new QLCInputSource(uni, ch)));
1✔
301
    }
302

303
    return true;
2✔
304
}
2✔
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