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

mcallegari / qlcplus / 6683238402

29 Oct 2023 12:10PM UTC coverage: 28.07%. Remained the same
6683238402

push

github

mcallegari
engine: fix build

15385 of 54809 relevant lines covered (28.07%)

20267.63 hits per line

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

86.96
/engine/src/qlcfixturedef.cpp
1
/*
2
  Q Light Controller Plus
3
  qlcfixturedef.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 <QXmlStreamWriter>
23
#include <iostream>
24
#include <QString>
25
#include <QDebug>
26
#include <QFile>
27

28
#include "qlcfixturemode.h"
29
#include "qlcfixturedef.h"
30
#include "qlcchannel.h"
31
#include "qlcfile.h"
32
#include "fixture.h"
33

34
QLCFixtureDef::QLCFixtureDef()
35,502✔
35
    : m_isLoaded(false)
36
    , m_isUser(false)
37
    , m_fileAbsolutePath(QString())
38
    , m_type(Dimmer)
35,502✔
39
{
40
}
35,502✔
41

42
QLCFixtureDef::QLCFixtureDef(const QLCFixtureDef* fixtureDef)
1✔
43
    : m_isLoaded(false)
44
    , m_isUser(false)
45
    , m_fileAbsolutePath(QString())
46
    , m_type(Dimmer)
1✔
47
{
48
    if (fixtureDef != NULL)
1✔
49
        *this = *fixtureDef;
1✔
50
}
1✔
51

52
QLCFixtureDef::~QLCFixtureDef()
35,275✔
53
{
54
    while (m_channels.isEmpty() == false)
36,038✔
55
        delete m_channels.takeFirst();
763✔
56

57
    while (m_modes.isEmpty() == false)
35,419✔
58
        delete m_modes.takeFirst();
144✔
59
}
35,275✔
60

61
QLCFixtureDef& QLCFixtureDef::operator=(const QLCFixtureDef& fixture)
1✔
62
{
63
    if (this != &fixture)
1✔
64
    {
65
        QListIterator <QLCChannel*> chit(fixture.m_channels);
2✔
66
        QListIterator <QLCFixtureMode*> modeit(fixture.m_modes);
2✔
67

68
        m_manufacturer = fixture.m_manufacturer;
1✔
69
        m_model = fixture.m_model;
1✔
70
        m_type = fixture.m_type;
1✔
71
        m_author = fixture.m_author;
1✔
72

73
        /* Clear all channels */
74
        while (m_channels.isEmpty() == false)
1✔
75
            delete m_channels.takeFirst();
×
76

77
        /* Copy channels from the other fixture */
78
        while (chit.hasNext() == true)
2✔
79
            m_channels.append(chit.next()->createCopy());
1✔
80

81
        /* Clear all modes */
82
        while (m_modes.isEmpty() == false)
1✔
83
            delete m_modes.takeFirst();
×
84

85
        /* Copy modes from the other fixture */
86
        while (modeit.hasNext() == true)
2✔
87
            m_modes.append(new QLCFixtureMode(this, modeit.next()));
1✔
88
    }
89

90
    return *this;
1✔
91
}
92

93
QString QLCFixtureDef::definitionSourceFile() const
2✔
94
{
95
    return m_fileAbsolutePath;
2✔
96
}
97

98
void QLCFixtureDef::setDefinitionSourceFile(const QString &absPath)
35,232✔
99
{
100
    m_fileAbsolutePath = absPath;
35,232✔
101
    m_isLoaded = false;
35,232✔
102
}
35,232✔
103

104
/****************************************************************************
105
 * General properties
106
 ****************************************************************************/
107

108
QString QLCFixtureDef::name() const
54✔
109
{
110
    return m_manufacturer + QString(" ") + m_model;
108✔
111
}
112

113
void QLCFixtureDef::setManufacturer(const QString& mfg)
35,526✔
114
{
115
    m_manufacturer = mfg;
35,526✔
116
}
35,526✔
117

118
QString QLCFixtureDef::manufacturer() const
27,992,800✔
119
{
120
    return m_manufacturer;
27,992,800✔
121
}
122

123
void QLCFixtureDef::setModel(const QString& model)
35,526✔
124
{
125
    m_model = model;
35,526✔
126
}
35,526✔
127

128
QString QLCFixtureDef::model() const
1,166,960✔
129
{
130
    return m_model;
1,166,960✔
131
}
132

133
void QLCFixtureDef::setType(const FixtureType type)
284✔
134
{
135
    m_type = type;
284✔
136
}
284✔
137

138
QLCFixtureDef::FixtureType QLCFixtureDef::type()
49✔
139
{
140
    return m_type;
49✔
141
}
142

143
QLCFixtureDef::FixtureType QLCFixtureDef::stringToType(const QString& type)
50✔
144
{
145
    if (type == "Color Changer") return ColorChanger;
50✔
146
    else if (type == "Dimmer") return Dimmer;
45✔
147
    else if (type == "Effect") return Effect;
45✔
148
    else if (type == "Fan") return Fan;
44✔
149
    else if (type == "Flower") return Flower;
44✔
150
    else if (type == "Hazer") return Hazer;
43✔
151
    else if (type == "Laser") return Laser;
42✔
152
    else if (type == "Moving Head") return MovingHead;
41✔
153
    else if (type == "Scanner") return Scanner;
28✔
154
    else if (type == "Smoke") return Smoke;
12✔
155
    else if (type == "Strobe") return Strobe;
11✔
156
    else if (type == "LED Bar (Beams)") return LEDBarBeams;
10✔
157
    else if (type == "LED Bar (Pixels)") return LEDBarPixels;
4✔
158

159
    return Other;
1✔
160
}
161

162
QString QLCFixtureDef::typeToString(QLCFixtureDef::FixtureType type)
28✔
163
{
164
    switch(type)
28✔
165
    {
166
        case ColorChanger: return "Color Changer";
2✔
167
        case Dimmer: return "Dimmer";
2✔
168
        case Effect: return "Effect";
2✔
169
        case Fan: return "Fan";
×
170
        case Flower: return "Flower";
2✔
171
        case Hazer: return "Hazer";
2✔
172
        case Laser: return "Laser";
2✔
173
        case MovingHead: return "Moving Head";
4✔
174
        case Scanner: return "Scanner";
3✔
175
        case Smoke: return "Smoke";
2✔
176
        case Strobe: return "Strobe";
2✔
177
        case LEDBarBeams: return "LED Bar (Beams)";
2✔
178
        case LEDBarPixels: return "LED Bar (Pixels)";
2✔
179
        default: return "Other";
1✔
180
    }
181
}
182

183
void QLCFixtureDef::setAuthor(const QString& author)
281✔
184
{
185
    m_author = author;
281✔
186
}
281✔
187

188
QString QLCFixtureDef::author()
3✔
189
{
190
    return m_author;
3✔
191
}
192

193
void QLCFixtureDef::checkLoaded(QString mapPath)
194✔
194
{
195
    // Already loaded ? Nothing to do
196
    if (m_isLoaded == true)
194✔
197
        return;
146✔
198

199
    if (manufacturer() == KXMLFixtureGeneric &&
106✔
200
       (model() == KXMLFixtureGeneric || model() == KXMLFixtureRGBPanel))
54✔
201
    {
202
        m_isLoaded = true;
×
203
        return;
×
204
    }
205
    if (m_fileAbsolutePath.isEmpty())
52✔
206
    {
207
        qWarning() << Q_FUNC_INFO << "Empty file path provided ! This is a trouble.";
4✔
208
        return;
4✔
209
    }
210

211
    QString absPath = QString("%1%2%3").arg(mapPath).arg(QDir::separator()).arg(m_fileAbsolutePath);
96✔
212
    qDebug() << "Loading fixture definition now... " << absPath;
48✔
213
    bool error = loadXML(absPath);
48✔
214
    if (error == false)
48✔
215
    {
216
        m_isLoaded = true;
48✔
217
        m_fileAbsolutePath = QString();
48✔
218
    }
219
}
220

221
bool QLCFixtureDef::isUser() const
×
222
{
223
    return m_isUser;
×
224
}
225

226
void QLCFixtureDef::setIsUser(bool flag)
1✔
227
{
228
    m_isUser = flag;
1✔
229
}
1✔
230

231
/****************************************************************************
232
 * Channels
233
 ****************************************************************************/
234

235
bool QLCFixtureDef::addChannel(QLCChannel* channel)
1,665✔
236
{
237
    if (channel != NULL && m_channels.contains(channel) == false)
1,665✔
238
    {
239
        m_channels.append(channel);
1,663✔
240
        return true;
1,663✔
241
    }
242
    else
243
    {
244
        return false;
2✔
245
    }
246
}
247

248
bool QLCFixtureDef::removeChannel(QLCChannel* channel)
7✔
249
{
250
    /* First remove the channel from all modes */
251
    QListIterator <QLCFixtureMode*> modeit(m_modes);
14✔
252
    while (modeit.hasNext() == true)
7✔
253
        modeit.next()->removeChannel(channel);
×
254

255
    /* Then remove the actual channel from this fixture definition */
256
    QMutableListIterator <QLCChannel*> chit(m_channels);
7✔
257
    while (chit.hasNext() == true)
9✔
258
    {
259
        if (chit.next() == channel)
4✔
260
        {
261
            chit.remove();
2✔
262
            delete channel;
2✔
263
            return true;
2✔
264
        }
265
    }
266

267
    return false;
5✔
268
}
269

270
QLCChannel* QLCFixtureDef::channel(const QString& name)
1,414✔
271
{
272
    QListIterator <QLCChannel*> it(m_channels);
2,828✔
273

274
    while (it.hasNext() == true)
20,920✔
275
    {
276
        QLCChannel* ch = it.next();
20,917✔
277
        if (ch->name() == name)
20,917✔
278
            return ch;
1,411✔
279
    }
280

281
    return NULL;
3✔
282
}
283

284
QList <QLCChannel*> QLCFixtureDef::channels() const
2,660✔
285
{
286
    return m_channels;
2,660✔
287
}
288

289
/****************************************************************************
290
 * Modes
291
 ****************************************************************************/
292

293
bool QLCFixtureDef::addMode(QLCFixtureMode* mode)
375✔
294
{
295
    if (mode != NULL && m_modes.contains(mode) == false)
375✔
296
    {
297
        m_modes.append(mode);
373✔
298
        return true;
373✔
299
    }
300
    else
301
    {
302
        return false;
2✔
303
    }
304
}
305

306
bool QLCFixtureDef::removeMode(QLCFixtureMode* mode)
7✔
307
{
308
    QMutableListIterator <QLCFixtureMode*> it(m_modes);
7✔
309
    while (it.hasNext() == true)
9✔
310
    {
311
        if (it.next() == mode)
4✔
312
        {
313
            it.remove();
2✔
314
            delete mode;
2✔
315
            return true;
2✔
316
        }
317
    }
318

319
    return false;
5✔
320
}
321

322
QLCFixtureMode *QLCFixtureDef::mode(const QString& name)
50✔
323
{
324
    QListIterator <QLCFixtureMode*> it(m_modes);
100✔
325

326
    while (it.hasNext() == true)
79✔
327
    {
328
        QLCFixtureMode *mode = it.next();
78✔
329
        if (mode->name() == name)
78✔
330
            return mode;
49✔
331
    }
332

333
    return NULL;
1✔
334
}
335

336
QList <QLCFixtureMode*> QLCFixtureDef::modes()
188✔
337
{
338
    return m_modes;
188✔
339
}
340

341
/****************************************************************************
342
 * Physical
343
 ****************************************************************************/
344

345
void QLCFixtureDef::setPhysical(const QLCPhysical& physical)
50✔
346
{
347
    m_physical = physical;
50✔
348
}
50✔
349

350
QLCPhysical QLCFixtureDef::physical() const
55✔
351
{
352
    return m_physical;
55✔
353
}
354

355
/****************************************************************************
356
 * XML operations
357
 ****************************************************************************/
358

359
QFile::FileError QLCFixtureDef::saveXML(const QString& fileName)
2✔
360
{
361
    QFile::FileError error;
362

363
    if (fileName.isEmpty() == true)
2✔
364
        return QFile::OpenError;
×
365

366
    QString tempFileName(fileName);
4✔
367
    tempFileName += ".temp";
2✔
368
    QFile file(tempFileName);
4✔
369
    if (file.open(QIODevice::WriteOnly) == false)
2✔
370
        return file.error();
1✔
371

372
    QXmlStreamWriter doc(&file);
2✔
373
    doc.setAutoFormatting(true);
1✔
374
    doc.setAutoFormattingIndent(1);
1✔
375
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
376
    doc.setCodec("UTF-8");
1✔
377
#endif
378
    QLCFile::writeXMLHeader(&doc, KXMLQLCFixtureDefDocument, author());
1✔
379

380
    doc.writeTextElement(KXMLQLCFixtureDefManufacturer, m_manufacturer);
1✔
381
    doc.writeTextElement(KXMLQLCFixtureDefModel, m_model);
1✔
382
    doc.writeTextElement(KXMLQLCFixtureDefType, typeToString(m_type));
1✔
383

384
    /* Channels */
385
    QListIterator <QLCChannel*> chit(m_channels);
2✔
386
    while (chit.hasNext() == true)
2✔
387
        chit.next()->saveXML(&doc);
1✔
388

389
    /* Modes */
390
    QListIterator <QLCFixtureMode*> modeit(m_modes);
2✔
391
    while (modeit.hasNext() == true)
2✔
392
        modeit.next()->saveXML(&doc);
1✔
393

394
    m_physical.saveXML(&doc);
1✔
395

396
    /* End the document and close all the open elements */
397
    error = QFile::NoError;
1✔
398
    doc.writeEndDocument();
1✔
399
    file.close();
1✔
400

401
    // Save to actual requested file name
402
    QFile currFile(fileName);
2✔
403
    if (currFile.exists() && !currFile.remove())
1✔
404
    {
405
        qWarning() << "Could not erase" << fileName;
×
406
        return currFile.error();
×
407
    }
408
    if (!file.rename(fileName))
1✔
409
    {
410
        qWarning() << "Could not rename" << tempFileName << "to" << fileName;
×
411
        return file.error();
×
412
    }
413

414
    return error;
1✔
415
}
416

417
QFile::FileError QLCFixtureDef::loadXML(const QString& fileName)
61✔
418
{
419
    QFile::FileError error = QFile::NoError;
61✔
420

421
    if (fileName.isEmpty() == true)
61✔
422
        return QFile::OpenError;
1✔
423

424
    QXmlStreamReader *doc = QLCFile::getXMLReader(fileName);
60✔
425
    if (doc == NULL || doc->device() == NULL || doc->hasError())
60✔
426
    {
427
        qWarning() << Q_FUNC_INFO << "Unable to read from" << fileName;
10✔
428
        return QFile::ReadError;
10✔
429
    }
430

431
    while (!doc->atEnd())
100✔
432
    {
433
        if (doc->readNext() == QXmlStreamReader::DTD)
100✔
434
            break;
50✔
435
    }
436
    if (doc->hasError())
50✔
437
    {
438
        QLCFile::releaseXMLReader(doc);
×
439
        return QFile::ResourceError;
×
440
    }
441

442
    if (doc->dtdName() == KXMLQLCFixtureDefDocument)
50✔
443
    {
444
        // qDebug() << Q_FUNC_INFO << "Loading " << fileName;
445
        if (loadXML(*doc) == true)
50✔
446
            error = QFile::NoError;
50✔
447
        else
448
        {
449
            qWarning() << fileName << QString("%1\nLine %2, column %3")
×
450
                        .arg(doc->errorString())
×
451
                        .arg(doc->lineNumber())
×
452
                        .arg(doc->columnNumber());
×
453
            error = QFile::ReadError;
×
454
        }
455
    }
456
    else
457
    {
458
        error = QFile::ReadError;
×
459
        qWarning() << Q_FUNC_INFO << fileName
×
460
                   << "is not a fixture definition file";
×
461
    }
462

463
    QLCFile::releaseXMLReader(doc);
50✔
464

465
    return error;
50✔
466
}
467

468
bool QLCFixtureDef::loadXML(QXmlStreamReader& doc)
50✔
469
{
470
    bool retval = false;
50✔
471

472
    if (doc.readNextStartElement() == false)
50✔
473
        return false;
×
474

475
    if (doc.name() == KXMLQLCFixtureDef)
50✔
476
    {
477
        while (doc.readNextStartElement())
1,142✔
478
        {
479
            if (doc.name() == KXMLQLCCreator)
1,092✔
480
            {
481
                loadCreator(doc);
50✔
482
            }
483
            else if (doc.name() == KXMLQLCFixtureDefManufacturer)
1,042✔
484
            {
485
                setManufacturer(doc.readElementText());
50✔
486
            }
487
            else if (doc.name() == KXMLQLCFixtureDefModel)
992✔
488
            {
489
                setModel(doc.readElementText());
50✔
490
            }
491
            else if (doc.name() == KXMLQLCFixtureDefType)
942✔
492
            {
493
                setType(stringToType(doc.readElementText()));
50✔
494
            }
495
            else if (doc.name() == KXMLQLCChannel)
892✔
496
            {
497
                QLCChannel* ch = new QLCChannel();
712✔
498
                if (ch->loadXML(doc) == true)
712✔
499
                {
500
                    /* Loading succeeded */
501
                    if (addChannel(ch) == false)
712✔
502
                    {
503
                        /* Channel already exists */
504
                        delete ch;
×
505
                    }
506
                }
507
                else
508
                {
509
                    /* Loading failed */
510
                    delete ch;
×
511
                }
512
            }
513
            else if (doc.name() == KXMLQLCFixtureMode)
180✔
514
            {
515
                QLCFixtureMode* mode = new QLCFixtureMode(this);
130✔
516
                if (mode->loadXML(doc) == true)
130✔
517
                {
518
                    /* Loading succeeded */
519
                    if (addMode(mode) == false)
130✔
520
                    {
521
                        /* Mode already exists */
522
                        delete mode;
×
523
                    }
524
                }
525
                else
526
                {
527
                    /* Loading failed */
528
                    delete mode;
×
529
                }
530
            }
531
            else if (doc.name() == KXMLQLCPhysical)
50✔
532
            {
533
                /* Global physical */
534
                QLCPhysical physical;
100✔
535
                physical.loadXML(doc);
50✔
536
                setPhysical(physical);
50✔
537
            }
538
            else
539
            {
540
                qWarning() << Q_FUNC_INFO << "Unknown Fixture tag: " << doc.name();
×
541
                doc.skipCurrentElement();
×
542
            }
543
        }
544

545
        retval = true;
50✔
546
    }
547
    else
548
    {
549
        qWarning() << Q_FUNC_INFO << "Fixture node not found";
×
550
        retval = false;
×
551
    }
552

553
    if (retval == true)
50✔
554
        m_isLoaded = true;
50✔
555
    return retval;
50✔
556
}
557

558
bool QLCFixtureDef::loadCreator(QXmlStreamReader &doc)
50✔
559
{
560
    if (doc.name() != KXMLQLCCreator)
50✔
561
    {
562
        qWarning() << Q_FUNC_INFO << "file creator information not found!";
×
563
        return false;
×
564
    }
565

566
    while (doc.readNextStartElement())
200✔
567
    {
568
        if (doc.name() == KXMLQLCCreatorName)
150✔
569
        {
570
            /* Ignore name */
571
            doc.skipCurrentElement();
50✔
572
        }
573
        else if (doc.name() == KXMLQLCCreatorVersion)
100✔
574
        {
575
            /* Ignore version */
576
            doc.skipCurrentElement();
50✔
577
        }
578
        else if (doc.name() == KXMLQLCCreatorAuthor)
50✔
579
        {
580
            setAuthor(doc.readElementText());
50✔
581
        }
582
        else
583
        {
584
            qWarning() << Q_FUNC_INFO << "unknown creator tag:" << doc.name();
×
585
            doc.skipCurrentElement();
×
586
        }
587
    }
588

589
    return true;
50✔
590
}
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