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

mcallegari / qlcplus / 7252848206

18 Dec 2023 07:26PM UTC coverage: 32.067% (+0.001%) from 32.066%
7252848206

push

github

mcallegari
Code style review #1427

199 of 628 new or added lines in 101 files covered. (31.69%)

8 existing lines in 2 files now uncovered.

15169 of 47304 relevant lines covered (32.07%)

23733.74 hits per line

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

89.59
/engine/src/qlcfixturemode.cpp
1
/*
2
  Q Light Controller Plus
3
  qlcfixturemode.cpp
4

5
  Copyright (C) Heikki Junnila
6
                Massimo Callegari
7

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

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

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

21
#include <QXmlStreamReader>
22
#include <iostream>
23
#include <QString>
24
#include <QDebug>
25
#include <QVector>
26

27
#include "qlcfixturemode.h"
28
#include "qlcfixturehead.h"
29
#include "qlcfixturedef.h"
30
#include "qlcchannel.h"
31
#include "qlcphysical.h"
32

33
QLCFixtureMode::QLCFixtureMode(QLCFixtureDef* fixtureDef)
401✔
34
    : m_fixtureDef(fixtureDef)
35
    , m_masterIntensityChannel(QLCChannel::invalid())
401✔
36
    , m_useGlobalPhysical(true)
802✔
37
{
38
    Q_ASSERT(fixtureDef != NULL);
401✔
39
}
401✔
40

41
QLCFixtureMode::QLCFixtureMode(QLCFixtureDef* fixtureDef, const QLCFixtureMode* mode)
3✔
42
    : m_fixtureDef(fixtureDef)
43
    , m_actsOnChannelsList(mode->actsOnChannelsList())
44
    , m_masterIntensityChannel(QLCChannel::invalid())
3✔
45
    , m_useGlobalPhysical(true)
6✔
46
{
47
    Q_ASSERT(fixtureDef != NULL);
3✔
48
    Q_ASSERT(mode != NULL);
3✔
49

50
    if (mode != NULL)
3✔
51
        *this = *mode;
3✔
52
}
3✔
53

54
QLCFixtureMode::~QLCFixtureMode()
338✔
55
{
56
}
338✔
57

58
QLCFixtureMode& QLCFixtureMode::operator=(const QLCFixtureMode& mode)
3✔
59
{
60
    if (this != &mode)
3✔
61
    {
62
        m_name = mode.m_name;
3✔
63
        m_useGlobalPhysical = mode.m_useGlobalPhysical;
3✔
64
        m_physical = mode.m_physical;
3✔
65
        m_heads = mode.m_heads;
3✔
66
        m_masterIntensityChannel = QLCChannel::invalid();
3✔
67
        m_actsOnChannelsList = mode.actsOnChannelsList();
3✔
68

69
        /* Clear the existing list of channels */
70
        m_channels.clear();
3✔
71

72
        Q_ASSERT(m_fixtureDef != NULL);
3✔
73

74
        quint32 i = 0;
3✔
75
        QVectorIterator <QLCChannel*> it(mode.m_channels);
6✔
76
        while (it.hasNext() == true)
12✔
77
        {
78
            /* Since m_fixtureDef might not be the same as
79
               mode.m_fixtureDef, we need to search for a
80
               channel with the same name from m_fixtureDef and
81
               not from mode.m_fixtureDef. If the channel in the
82
               other mode is deleted, the one in this copied mode
83
               will be invalid and we end up in a crash. */
84
            QLCChannel* ch = it.next();
9✔
85
            QLCChannel* actual = m_fixtureDef->channel(ch->name());
9✔
86
            if (actual != NULL)
9✔
87
                insertChannel(actual, i++);
7✔
88
            else
89
                qWarning() << Q_FUNC_INFO << "Unable to find channel"
4✔
90
                           << ch->name() << "for mode"
4✔
91
                           << m_name << "from its fixture definition";
2✔
92
        }
93
    }
94

95
    return *this;
3✔
96
}
97

98
/****************************************************************************
99
 * Name
100
 ****************************************************************************/
101

102
void QLCFixtureMode::setName(const QString &name)
378✔
103
{
104
    m_name = name;
378✔
105
}
378✔
106

107
QString QLCFixtureMode::name() const
112✔
108
{
109
    return m_name;
112✔
110
}
111

112
/*****************************************************************************
113
 * Fixture definition
114
 *****************************************************************************/
115

116
QLCFixtureDef* QLCFixtureMode::fixtureDef() const
56✔
117
{
118
    return m_fixtureDef;
56✔
119
}
120

121
/****************************************************************************
122
 * Channels
123
 ****************************************************************************/
124

125
bool QLCFixtureMode::insertChannel(QLCChannel* channel, quint32 index)
2,407✔
126
{
127
    if (channel == NULL)
2,407✔
128
    {
129
        qWarning() << Q_FUNC_INFO << "Will not add a NULL channel to mode"
2✔
130
                   << m_name;
1✔
131
        return false;
1✔
132
    }
133

134
    Q_ASSERT(m_fixtureDef != NULL);
2,406✔
135

136
    if (m_fixtureDef->channels().contains(channel) == true)
2,406✔
137
    {
138
        if (m_channels.contains(channel) == false)
2,405✔
139
        {
140
            if (index >= quint32(m_channels.size()))
2,404✔
141
                m_channels.append(channel);
2,402✔
142
            else
143
                m_channels.insert(index, channel);
2✔
144
            return true;
2,404✔
145
        }
146
        else
147
        {
148
            qWarning() << Q_FUNC_INFO << "Channel" << channel->name()
2✔
149
                       << "is already a member of mode" << m_name;
1✔
150
            return false;
1✔
151
        }
152
    }
153
    else
154
    {
155
        qWarning() << Q_FUNC_INFO << "Will not add channel" << channel->name()
2✔
156
                   << "to mode" << m_name
1✔
157
                   << "because the channel does not belong to mode's"
1✔
158
                   << "parent fixture definition.";
1✔
159
        return false;
1✔
160
    }
161
}
162

163
bool QLCFixtureMode::removeChannel(const QLCChannel* channel)
7✔
164
{
165
    QMutableVectorIterator <QLCChannel*> it(m_channels);
7✔
166
    while (it.hasNext() == true)
17✔
167
    {
168
        if (it.next() == channel)
15✔
169
        {
170
            /* Don't delete the channel since QLCFixtureModes
171
               don't own them. QLCFixtureDefs do. */
172
            it.remove();
5✔
173
            return true;
5✔
174
        }
175
    }
176

177
    return false;
2✔
178
}
179

180
bool QLCFixtureMode::replaceChannel(QLCChannel *currChannel, QLCChannel *newChannel)
×
181
{
182
    if (currChannel == NULL || newChannel == NULL)
×
183
        return false;
×
184

185
    int chIndex = m_channels.indexOf(currChannel);
×
186
    if (chIndex == -1)
×
187
        return false;
×
188

189
    m_channels.replace(chIndex, newChannel);
×
190

191
    return true;
×
192
}
193

194
void QLCFixtureMode::removeAllChannels()
×
195
{
196
    m_channels.clear();
×
197
}
×
198

199
QLCChannel* QLCFixtureMode::channel(const QString& name) const
6✔
200
{
201
    QVectorIterator <QLCChannel*> it(m_channels);
12✔
202
    while (it.hasNext() == true)
20✔
203
    {
204
        QLCChannel* ch = it.next();
18✔
205
        Q_ASSERT(ch != NULL);
18✔
206
        if (ch->name() == name)
18✔
207
            return ch;
4✔
208
    }
209

210
    return NULL;
2✔
211
}
212

213
QLCChannel* QLCFixtureMode::channel(quint32 ch) const
801,443✔
214
{
215
    return m_channels.value(ch, NULL);
801,443✔
216
}
217

218
QVector <QLCChannel*> QLCFixtureMode::channels() const
14,764✔
219
{
220
    return m_channels;
14,764✔
221
}
222

223
quint32 QLCFixtureMode::channelNumber(QLCChannel* channel) const
6✔
224
{
225
    if (channel == NULL)
6✔
226
        return QLCChannel::invalid();
1✔
227

228
    int idx = m_channels.indexOf(channel);
5✔
229
    return idx == -1 ? QLCChannel::invalid() : idx;
5✔
230
}
231

232
quint32 QLCFixtureMode::channelNumber(QLCChannel::Group group, QLCChannel::ControlByte cByte) const
3,864✔
233
{
234
    for (int i = 0; i < m_channels.size(); i++)
48,796✔
235
    {
236
        if (m_channels.at(i)->group() == group &&
45,291✔
237
            m_channels.at(i)->controlByte() == cByte)
308✔
238
            return i;
51✔
239
    }
240

241
    return QLCChannel::invalid();
3,813✔
242
}
243

244
quint32 QLCFixtureMode::masterIntensityChannel() const
40✔
245
{
246
    return m_masterIntensityChannel;
40✔
247
}
248

249
void QLCFixtureMode::updateActsOnChannel(QLCChannel *mainChannel, QLCChannel *actsOnChannel)
×
250
{
251
    m_actsOnChannelsList.insert(mainChannel, actsOnChannel);
×
252
}
×
253

254
QHash<QLCChannel *, QLCChannel *> QLCFixtureMode::actsOnChannelsList() const
6✔
255
{
256
    return m_actsOnChannelsList;
6✔
257
}
258

259
/*****************************************************************************
260
 * Heads
261
 *****************************************************************************/
262

263
void QLCFixtureMode::insertHead(int index, const QLCFixtureHead& head)
1,002✔
264
{
265
    if (index < 0 || index >= m_heads.size())
1,002✔
266
        m_heads.append(head);
1,001✔
267
    else
268
        m_heads.insert(index, head);
1✔
269
}
1,002✔
270

271
void QLCFixtureMode::removeHead(int index)
4✔
272
{
273
    if (index >= 0 && index < m_heads.size())
4✔
274
        m_heads.remove(index);
3✔
275
}
4✔
276

277
void QLCFixtureMode::replaceHead(int index, const QLCFixtureHead& head)
2✔
278
{
279
    if (index >= 0 && index < m_heads.size())
2✔
280
        m_heads[index] = head;
1✔
281
}
2✔
282

283
QVector <QLCFixtureHead> const& QLCFixtureMode::heads() const
3,189✔
284
{
285
    return m_heads;
3,189✔
286
}
287

288
int QLCFixtureMode::headForChannel(quint32 chnum) const
1,031✔
289
{
290
    for (int i = 0; i < m_heads.size(); i++)
3,882✔
291
    {
292
        if (m_heads[i].channels().contains(chnum) == true)
3,770✔
293
            return i;
919✔
294
    }
295

296
    return -1;
112✔
297
}
298

299
void QLCFixtureMode::cacheHeads()
586✔
300
{
301
    for (int i = 0; i < m_heads.size(); i++)
1,939✔
302
    {
303
        QLCFixtureHead& head(m_heads[i]);
1,353✔
304
        head.cacheChannels(this);
1,353✔
305
    }
306

307
    for (int i = 0; i < m_channels.size(); i++)
3,827✔
308
    {
309
        if (m_channels.at(i)->group() == QLCChannel::Intensity &&
3,353✔
310
            m_channels.at(i)->controlByte() == QLCChannel::MSB &&
1,867✔
311
            m_channels.at(i)->colour() == QLCChannel::NoColour &&
6,251✔
312
            headForChannel(i) == -1)
1,031✔
313
        {
314
            m_masterIntensityChannel = i;
112✔
315
            break;
112✔
316
        }
317
    }
318
}
586✔
319

320
/****************************************************************************
321
 * Physical
322
 ****************************************************************************/
323

324
void QLCFixtureMode::setPhysical(const QLCPhysical& physical)
234✔
325
{
326
    m_useGlobalPhysical = false;
234✔
327
    m_physical = physical;
234✔
328
}
234✔
329

330
void QLCFixtureMode::resetPhysical()
×
331
{
332
    m_useGlobalPhysical = true;
×
333
}
×
334

335
bool QLCFixtureMode::useGlobalPhysical()
2✔
336
{
337
    return m_useGlobalPhysical;
2✔
338
}
339

340
QLCPhysical QLCFixtureMode::physical() const
66✔
341
{
342
    if (m_useGlobalPhysical)
66✔
343
        return fixtureDef()->physical();
55✔
344

345
    return m_physical;
11✔
346
}
347

348
/****************************************************************************
349
 * Load & Save
350
 ****************************************************************************/
351

352
bool QLCFixtureMode::loadXML(QXmlStreamReader &doc)
139✔
353
{
354
    if (doc.name() != KXMLQLCFixtureMode)
139✔
355
    {
356
        qWarning() << Q_FUNC_INFO << "Mode tag not found";
1✔
357
        return false;
1✔
358
    }
359

360
    /* Mode name */
361
    QString str = doc.attributes().value(KXMLQLCFixtureModeName).toString();
414✔
362
    if (str.isEmpty() == true)
138✔
363
    {
364
        qWarning() << Q_FUNC_INFO << "Mode has no name";
1✔
365
        return false;
1✔
366
    }
367
    else
368
    {
369
        setName(str);
137✔
370
    }
371

372
    /* Temporary list with mode's channels pointer and acts on indexes. */
373
    QList<ChannelActsOnData> listChannelsWithActsOnIndex;
137✔
374

375
    /* Subtags */
376
    while (doc.readNextStartElement())
1,742✔
377
    {
378
        if (doc.name() == KXMLQLCFixtureModeChannel)
1,605✔
379
        {
380
            /* Channel */
381
            Q_ASSERT(m_fixtureDef != NULL);
1,419✔
382
            str = doc.attributes().value(KXMLQLCFixtureModeChannelNumber).toString();
1,419✔
383

384
            int actsOnChannelIndex = -1;
1,419✔
385

386
            if (doc.attributes().hasAttribute(KXMLQLCFixtureModeChannelActsOn))
1,419✔
387
            {
388
                actsOnChannelIndex = doc.attributes().value(KXMLQLCFixtureModeChannelActsOn).toInt();
×
389
            }
390

391
            QLCChannel *currentChannel = m_fixtureDef->channel(doc.readElementText());
1,419✔
392

393
            ChannelActsOnData channelActsData(currentChannel, actsOnChannelIndex);
1,419✔
394

395
            listChannelsWithActsOnIndex.append(channelActsData);
1,419✔
396

397
            insertChannel(currentChannel,
1,419✔
398
                          str.toInt());
1,419✔
399
        }
400
        else if (doc.name() == KXMLQLCFixtureHead)
186✔
401
        {
402
            /* Head */
403
            QLCFixtureHead head;
368✔
404
            if (head.loadXML(doc) == true)
184✔
405
                insertHead(-1, head);
184✔
406
        }
407
        else if (doc.name() == KXMLQLCPhysical)
2✔
408
        {
409
            /* Physical */
410
            QLCPhysical physical;
2✔
411
            physical.loadXML(doc);
1✔
412
            setPhysical(physical);
1✔
413
        }
414
        else
415
        {
416
            qWarning() << Q_FUNC_INFO << "Unknown Fixture Mode tag:" << doc.name();
1✔
417
            doc.skipCurrentElement();
1✔
418
        }
419
    }
420

421
    // Set acts on channels
422

423
    foreach (ChannelActsOnData channelSctsOnData, listChannelsWithActsOnIndex)
2,975✔
424
    {
425
        if (m_channels.contains(channelSctsOnData.channel) &&
1,419✔
426
                channelSctsOnData.actsOnIndex >= 0 &&
1,419✔
427
                m_channels.size() > channelSctsOnData.actsOnIndex)
×
428
        {
429
            m_actsOnChannelsList.insert(channelSctsOnData.channel,
430
                                        m_channels.at(channelSctsOnData.actsOnIndex));
×
431
        }
432
    }
433

434
    // Cache all head channels
435
    cacheHeads();
137✔
436

437
    return true;
137✔
438
}
439

440
bool QLCFixtureMode::saveXML(QXmlStreamWriter *doc)
3✔
441
{
442
    int i = 0;
3✔
443

444
    Q_ASSERT(doc != NULL);
3✔
445

446
    /* Mode entry */
447
    doc->writeStartElement(KXMLQLCFixtureMode);
3✔
448
    doc->writeAttribute(KXMLQLCFixtureModeName, m_name);
3✔
449

450
    if (m_useGlobalPhysical == false)
3✔
451
        m_physical.saveXML(doc);
1✔
452

453
    /* Channels */
454
    QVectorIterator <QLCChannel*> it(m_channels);
6✔
455
    while (it.hasNext() == true)
8✔
456
    {
457
        QLCChannel* channel = it.next();
5✔
458

459
        doc->writeStartElement(KXMLQLCFixtureModeChannel);
5✔
460
        doc->writeAttribute(KXMLQLCFixtureModeChannelNumber, QString::number(i++));
5✔
461

462
        if (m_actsOnChannelsList.contains(channel))
5✔
463
        {
464
            QLCChannel *ChannelActsOn = m_actsOnChannelsList.value(channel);
×
NEW
465
            if (ChannelActsOn != NULL){
×
466
                doc->writeAttribute(KXMLQLCFixtureModeChannelActsOn, QString::number(m_channels.indexOf(ChannelActsOn)));
×
467
            }
468
        }
469

470
        doc->writeCharacters(channel->name());
5✔
471
        doc->writeEndElement();
5✔
472
    }
473

474
    /* Heads */
475
    QVectorIterator <QLCFixtureHead> hit(m_heads);
3✔
476
    while (hit.hasNext() == true)
6✔
477
        hit.next().saveXML(doc);
3✔
478

479
    doc->writeEndElement();
3✔
480

481
    return true;
6✔
482
}
483

484
QLCFixtureMode::ChannelActsOnData::ChannelActsOnData(QLCChannel *newChannel, int newAcsOnIndex) :
1,419✔
485
    channel(newChannel),
486
    actsOnIndex(newAcsOnIndex)
1,419✔
487
{}
1,419✔
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