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

mcallegari / qlcplus / 19144422256

06 Nov 2025 05:33PM UTC coverage: 34.256% (-0.1%) from 34.358%
19144422256

push

github

mcallegari
Back to 5.1.0 debug

17718 of 51723 relevant lines covered (34.26%)

19528.23 hits per line

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

28.54
/engine/src/monitorproperties.cpp
1
/*
2
  Q Light Controller Plus
3
  monitorproperties.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
#include <QFont>
24

25
#include "monitorproperties.h"
26
#include "qlcconfig.h"
27
#include "qlcfile.h"
28
#include "doc.h"
29

30
#define KXMLQLCMonitorDisplay       QStringLiteral("DisplayMode")
31
#define KXMLQLCMonitorChannels      QStringLiteral("ChannelStyle")
32
#define KXMLQLCMonitorValues        QStringLiteral("ValueStyle")
33
#define KXMLQLCMonitorFont          QStringLiteral("Font")
34
#define KXMLQLCMonitorGrid          QStringLiteral("Grid")
35
#define KXMLQLCMonitorGridWidth     QStringLiteral("Width")
36
#define KXMLQLCMonitorGridHeight    QStringLiteral("Height")
37
#define KXMLQLCMonitorGridDepth     QStringLiteral("Depth")
38
#define KXMLQLCMonitorGridUnits     QStringLiteral("Units")
39
#define KXMLQLCMonitorPointOfView   QStringLiteral("POV")
40
#define KXMLQLCMonitorItemID        QStringLiteral("ID")
41
#define KXMLQLCMonitorShowLabels    QStringLiteral("ShowLabels")
42

43
#define KXMLQLCMonitorCommonBackground  QStringLiteral("Background")
44
#define KXMLQLCMonitorCustomBgItem      QStringLiteral("BackgroundItem")
45

46
#define KXMLQLCMonitorFixtureItem   QStringLiteral("FxItem")
47
#define KXMLQLCMonitorStageItem     QStringLiteral("StageItem")
48
#define KXMLQLCMonitorMeshItem      QStringLiteral("MeshItem")
49
#define KXMLQLCMonitorItemName      QStringLiteral("Name")
50
#define KXMLQLCMonitorItemRes       QStringLiteral("Res")
51

52
#define KXMLQLCMonitorItemXPosition     QStringLiteral("XPos")
53
#define KXMLQLCMonitorItemYPosition     QStringLiteral("YPos")
54
#define KXMLQLCMonitorItemZPosition     QStringLiteral("ZPos")
55
#define KXMLQLCMonitorItemXRotation     QStringLiteral("XRot")
56
#define KXMLQLCMonitorItemYRotation     QStringLiteral("YRot")
57
#define KXMLQLCMonitorItemZRotation     QStringLiteral("ZRot")
58
#define KXMLQLCMonitorFixtureRotation   QStringLiteral("Rotation") // LEGACY
59
#define KXMLQLCMonitorItemXScale        QStringLiteral("XScale")
60
#define KXMLQLCMonitorItemYScale        QStringLiteral("YScale")
61
#define KXMLQLCMonitorItemZScale        QStringLiteral("ZScale")
62

63
#define KXMLQLCMonitorFixtureHeadIndex      QStringLiteral("Head")
64
#define KXMLQLCMonitorFixtureLinkedIndex    QStringLiteral("Linked")
65

66
#define KXMLQLCMonitorFixtureGelColor   QStringLiteral("GelColor")
67
#define KXMLQLCMonitorFixtureFixedZoom  QStringLiteral("FixedZoom")
68

69
#define KXMLQLCMonitorFixtureHiddenFlag     QStringLiteral("Hidden")
70
#define KXMLQLCMonitorFixtureInvPanFlag     QStringLiteral("InvertedPan")
71
#define KXMLQLCMonitorFixtureInvTiltFlag    QStringLiteral("InvertedTilt")
72

73
#define GRID_DEFAULT_WIDTH  5
74
#define GRID_DEFAULT_HEIGHT 3
75
#define GRID_DEFAULT_DEPTH  5
76

77
MonitorProperties::MonitorProperties()
5✔
78
    : m_displayMode(DMX)
5✔
79
    , m_channelStyle(DMXChannels)
5✔
80
    , m_valueStyle(DMXValues)
5✔
81
    , m_gridSize(QVector3D(GRID_DEFAULT_WIDTH, GRID_DEFAULT_HEIGHT, GRID_DEFAULT_DEPTH))
5✔
82
    , m_gridUnits(Meters)
5✔
83
    , m_pointOfView(Undefined)
5✔
84
    , m_stageType(StageSimple)
5✔
85
    , m_showLabels(false)
10✔
86
{
87
    m_font = QFont("Arial", 12);
5✔
88
}
5✔
89

90
void MonitorProperties::reset()
10✔
91
{
92
    m_gridSize = QVector3D(GRID_DEFAULT_WIDTH, GRID_DEFAULT_HEIGHT, GRID_DEFAULT_DEPTH);
10✔
93
    m_gridUnits = Meters;
10✔
94
    m_pointOfView = Undefined;
10✔
95
    m_stageType = StageSimple;
10✔
96
    m_showLabels = false;
10✔
97
    m_fixtureItems.clear();
10✔
98
    m_genericItems.clear();
10✔
99
    m_commonBackgroundImage = QString();
10✔
100
}
10✔
101

102
/********************************************************************
103
 * Environment
104
 ********************************************************************/
105

106
void MonitorProperties::setPointOfView(MonitorProperties::PointOfView pov)
1✔
107
{
108
    if (pov == m_pointOfView)
1✔
109
        return;
×
110

111
    if (m_pointOfView == Undefined)
1✔
112
    {
113
        QVector3D gSize = gridSize();
1✔
114
        float units = gridUnits() == MonitorProperties::Meters ? 1000.0 : 304.8;
1✔
115

116
        if (gSize.z() == 0)
1✔
117
        {
118
            // convert the grid size first
119
            switch (pov)
×
120
            {
121
                case TopView:
×
122
                    setGridSize(QVector3D(gSize.x(), GRID_DEFAULT_HEIGHT, gSize.y()));
×
123
                break;
×
124
                case RightSideView:
×
125
                case LeftSideView:
126
                    setGridSize(QVector3D(GRID_DEFAULT_WIDTH, gSize.x(), gSize.x()));
×
127
                break;
×
128
                default:
×
129
                break;
×
130
            }
131
        }
132

133
        foreach (quint32 fid, fixtureItemsID())
2✔
134
        {
135
            foreach (quint32 subID, fixtureIDList(fid))
×
136
            {
137
                QVector3D pos = fixturePosition(fid, fixtureHeadIndex(subID), fixtureLinkedIndex(subID));
×
138
                QVector3D newPos;
×
139

140
                switch (pov)
×
141
                {
142
                    case TopView:
×
143
                    {
144
                        newPos = QVector3D(pos.x(), 1000, pos.y());
×
145
                    }
146
                    break;
×
147
                    case RightSideView:
×
148
                    {
149
                        newPos = QVector3D(0, pos.y(), (gridSize().z() * units) - pos.x());
×
150
                    }
151
                    break;
×
152
                    case LeftSideView:
×
153
                    {
154
                        newPos = QVector3D(0, pos.y(), pos.x());
×
155
                    }
156
                    break;
×
157
                    default:
×
158
                        newPos = QVector3D(pos.x(), (gridSize().y() * units) - pos.y(), 1000);
×
159
                    break;
×
160
                }
161
                setFixturePosition(fid, fixtureHeadIndex(subID), fixtureLinkedIndex(subID), newPos);
×
162
            }
×
163
        }
1✔
164
    }
165
    m_pointOfView = pov;
1✔
166
}
167

168
/********************************************************************
169
 * Fixture items
170
 ********************************************************************/
171

172
void MonitorProperties::removeFixture(quint32 fid)
1✔
173
{
174
    if (m_fixtureItems.contains(fid))
1✔
175
        m_fixtureItems.take(fid);
1✔
176
}
1✔
177

178
void MonitorProperties::removeFixture(quint32 fid, quint16 head, quint16 linked)
×
179
{
180
    if (m_fixtureItems.contains(fid) == false)
×
181
        return;
×
182

183
    // if no sub items are present,
184
    // the fixture can be removed completely
185
    if (m_fixtureItems[fid].m_subItems.count() == 0)
×
186
    {
187
        m_fixtureItems.take(fid);
×
188
        return;
×
189
    }
190

191
    quint32 subID = fixtureSubID(head, linked);
×
192
    m_fixtureItems[fid].m_subItems.remove(subID);
×
193
}
194

195
quint32 MonitorProperties::fixtureSubID(quint32 headIndex, quint32 linkedIndex) const
×
196
{
197
    return ((headIndex << 16) | linkedIndex);
×
198
}
199

200
quint16 MonitorProperties::fixtureHeadIndex(quint32 mapID) const
×
201
{
202
    return (quint16)(mapID >> 16);
×
203
}
204

205
quint16 MonitorProperties::fixtureLinkedIndex(quint32 mapID) const
×
206
{
207
    return (quint16)(mapID & 0x0000FFFF);
×
208
}
209

210
bool MonitorProperties::containsItem(quint32 fid, quint16 head, quint16 linked)
×
211
{
212
    if (m_fixtureItems.contains(fid) == false)
×
213
        return false;
×
214

215
    if (head == 0 && linked == 0)
×
216
        return true;
×
217

218
    quint32 subID = fixtureSubID(head, linked);
×
219
    return m_fixtureItems[fid].m_subItems.contains(subID);
×
220
}
221

222
void MonitorProperties::setFixturePosition(quint32 fid, quint16 head, quint16 linked, QVector3D pos)
5✔
223
{
224
    //qDebug() << Q_FUNC_INFO << "X:" << pos.x() << "Y:" << pos.y();
225
    if (head == 0 && linked == 0)
5✔
226
    {
227
        m_fixtureItems[fid].m_baseItem.m_position = pos;
5✔
228
    }
229
    else
230
    {
231
        quint32 subID = fixtureSubID(head, linked);
×
232
        m_fixtureItems[fid].m_subItems[subID].m_position = pos;
×
233
    }
234
}
5✔
235

236
QVector3D MonitorProperties::fixturePosition(quint32 fid, quint16 head, quint16 linked) const
1✔
237
{
238
    if (head == 0 && linked == 0)
1✔
239
    {
240
        return m_fixtureItems[fid].m_baseItem.m_position;
1✔
241
    }
242
    else
243
    {
244
        quint32 subID = fixtureSubID(head, linked);
×
245
        return m_fixtureItems[fid].m_subItems[subID].m_position;
×
246
    }
247
}
248

249
void MonitorProperties::setFixtureRotation(quint32 fid, quint16 head, quint16 linked, QVector3D degrees)
1✔
250
{
251
    if (head == 0 && linked == 0)
1✔
252
    {
253
        m_fixtureItems[fid].m_baseItem.m_rotation = degrees;
1✔
254
    }
255
    else
256
    {
257
        quint32 subID = fixtureSubID(head, linked);
×
258
        m_fixtureItems[fid].m_subItems[subID].m_rotation = degrees;
×
259
    }
260
}
1✔
261

262
QVector3D MonitorProperties::fixtureRotation(quint32 fid, quint16 head, quint16 linked) const
1✔
263
{
264
    if (head == 0 && linked == 0)
1✔
265
    {
266
        return m_fixtureItems[fid].m_baseItem.m_rotation;
1✔
267
    }
268
    else
269
    {
270
        quint32 subID = fixtureSubID(head, linked);
×
271
        return m_fixtureItems[fid].m_subItems[subID].m_rotation;
×
272
    }
273
}
274

275
void MonitorProperties::setFixtureGelColor(quint32 fid, quint16 head, quint16 linked, QColor col)
1✔
276
{
277
    //qDebug() << Q_FUNC_INFO << "Gel color:" << col;
278
    if (head == 0 && linked == 0)
1✔
279
    {
280
        m_fixtureItems[fid].m_baseItem.m_color = col;
1✔
281
    }
282
    else
283
    {
284
        quint32 subID = fixtureSubID(head, linked);
×
285
        m_fixtureItems[fid].m_subItems[subID].m_color = col;
×
286
    }
287
}
1✔
288

289
QColor MonitorProperties::fixtureGelColor(quint32 fid, quint16 head, quint16 linked) const
1✔
290
{
291
    if (head == 0 && linked == 0)
1✔
292
    {
293
        return m_fixtureItems[fid].m_baseItem.m_color;
1✔
294
    }
295
    else
296
    {
297
        quint32 subID = fixtureSubID(head, linked);
×
298
        return m_fixtureItems[fid].m_subItems[subID].m_color;
×
299
    }
300
}
301

302
void MonitorProperties::setFixtureFixedZoom(quint32 fid, quint16 head, quint16 linked, int degrees)
×
303
{
304
    if (head == 0 && linked == 0)
×
305
    {
306
        m_fixtureItems[fid].m_baseItem.m_zoom = degrees;
×
307
    }
308
    else
309
    {
310
        quint32 subID = fixtureSubID(head, linked);
×
311
        m_fixtureItems[fid].m_subItems[subID].m_zoom = degrees;
×
312
    }
313
}
×
314

315
int MonitorProperties::fixtureFixedZoom(quint32 fid, quint16 head, quint16 linked) const
×
316
{
317
    if (head == 0 && linked == 0)
×
318
    {
319
        return m_fixtureItems[fid].m_baseItem.m_zoom;
×
320
    }
321
    else
322
    {
323
        quint32 subID = fixtureSubID(head, linked);
×
324
        return m_fixtureItems[fid].m_subItems[subID].m_zoom;
×
325
    }
326
}
327

328
void MonitorProperties::setFixtureName(quint32 fid, quint16 head, quint16 linked, QString name)
1✔
329
{
330
    if (head == 0 && linked == 0)
1✔
331
    {
332
        m_fixtureItems[fid].m_baseItem.m_name = name;
1✔
333
    }
334
    else
335
    {
336
        quint32 subID = fixtureSubID(head, linked);
×
337
        m_fixtureItems[fid].m_subItems[subID].m_name = name;
×
338
    }
339
}
1✔
340

341
QString MonitorProperties::fixtureName(quint32 fid, quint16 head, quint16 linked) const
1✔
342
{
343
    if (head == 0 && linked == 0)
1✔
344
    {
345
        return m_fixtureItems[fid].m_baseItem.m_name;
1✔
346
    }
347
    else
348
    {
349
        quint32 subID = fixtureSubID(head, linked);
×
350
        return m_fixtureItems[fid].m_subItems[subID].m_name;
×
351
    }
352
}
353

354
void MonitorProperties::setFixtureFlags(quint32 fid, quint16 head, quint16 linked, quint32 flags)
1✔
355
{
356
    if (head == 0 && linked == 0)
1✔
357
    {
358
        m_fixtureItems[fid].m_baseItem.m_flags = flags;
1✔
359
    }
360
    else
361
    {
362
        quint32 subID = fixtureSubID(head, linked);
×
363
        m_fixtureItems[fid].m_subItems[subID].m_flags = flags;
×
364
    }
365
}
1✔
366

367
quint32 MonitorProperties::fixtureFlags(quint32 fid, quint16 head, quint16 linked) const
1✔
368
{
369
    if (head == 0 && linked == 0)
1✔
370
    {
371
        return m_fixtureItems[fid].m_baseItem.m_flags;
1✔
372
    }
373
    else
374
    {
375
        quint32 subID = fixtureSubID(head, linked);
×
376
        return m_fixtureItems[fid].m_subItems[subID].m_flags;
×
377
    }
378
}
379

380
PreviewItem MonitorProperties::fixtureItem(quint32 fid, quint16 head, quint16 linked) const
×
381
{
382
    if (head == 0 && linked == 0)
×
383
    {
384
        return m_fixtureItems[fid].m_baseItem;
×
385
    }
386
    else
387
    {
388
        quint32 subID = fixtureSubID(head, linked);
×
389
        return m_fixtureItems[fid].m_subItems[subID];
×
390
    }
391
}
392

393
void MonitorProperties::setFixtureItem(quint32 fid, quint16 head, quint16 linked, PreviewItem props)
×
394
{
395
    if (head == 0 && linked == 0)
×
396
    {
397
        m_fixtureItems[fid].m_baseItem = props;
×
398
    }
399
    else
400
    {
401
        quint32 subID = fixtureSubID(head, linked);
×
402
        m_fixtureItems[fid].m_subItems[subID] = props;
×
403
    }
404
}
×
405

406
QList<quint32> MonitorProperties::fixtureIDList(quint32 fid) const
×
407
{
408
    QList<quint32> list;
×
409
    if (m_fixtureItems.contains(fid) == false)
×
410
        return list;
×
411

412
    // add the basic fixture item ID
413
    list.append(0);
×
414

415
    FixturePreviewItem fxItem = m_fixtureItems[fid];
×
416
    list.append(fxItem.m_subItems.keys());
×
417

418
    return list;
×
419
}
×
420

421
/********************************************************************
422
 * Generic items
423
 ********************************************************************/
424

425
QList<quint32> MonitorProperties::genericItemsID()
2✔
426
{
427
    return m_genericItems.keys();
2✔
428
}
429

430
QString MonitorProperties::itemName(quint32 itemID)
1✔
431
{
432
    if (m_genericItems[itemID].m_name.isEmpty())
1✔
433
    {
434
        QFileInfo rName(m_genericItems[itemID].m_resource);
×
435
        return rName.baseName();
×
436
    }
×
437

438
    return m_genericItems[itemID].m_name;
1✔
439
}
440

441
void MonitorProperties::setItemName(quint32 itemID, QString name)
2✔
442
{
443
    m_genericItems[itemID].m_name = name;
2✔
444
}
2✔
445

446
QString MonitorProperties::itemResource(quint32 itemID)
1✔
447
{
448
    return m_genericItems[itemID].m_resource;
1✔
449
}
450

451
void MonitorProperties::setItemResource(quint32 itemID, QString resource)
1✔
452
{
453
    m_genericItems[itemID].m_resource = resource;
1✔
454
}
1✔
455

456
QVector3D MonitorProperties::itemPosition(quint32 itemID)
1✔
457
{
458
    return m_genericItems[itemID].m_position;
1✔
459
}
460

461
void MonitorProperties::setItemPosition(quint32 itemID, QVector3D pos)
1✔
462
{
463
    m_genericItems[itemID].m_position = pos;
1✔
464
}
1✔
465

466
QVector3D MonitorProperties::itemRotation(quint32 itemID)
1✔
467
{
468
    return m_genericItems[itemID].m_rotation;
1✔
469
}
470

471
void MonitorProperties::setItemRotation(quint32 itemID, QVector3D rot)
1✔
472
{
473
    m_genericItems[itemID].m_rotation = rot;
1✔
474
}
1✔
475

476
QVector3D MonitorProperties::itemScale(quint32 itemID)
1✔
477
{
478
    if (m_genericItems[itemID].m_scale.isNull())
1✔
479
        return QVector3D(1.0, 1.0, 1.0);
×
480

481
    return m_genericItems[itemID].m_scale;
1✔
482
}
483

484
void MonitorProperties::setItemScale(quint32 itemID, QVector3D scale)
1✔
485
{
486
    m_genericItems[itemID].m_scale = scale;
1✔
487
}
1✔
488

489
quint32 MonitorProperties::itemFlags(quint32 itemID)
1✔
490
{
491
    return m_genericItems[itemID].m_flags;
1✔
492
}
493

494
void MonitorProperties::setItemFlags(quint32 itemID, quint32 flags)
1✔
495
{
496
    m_genericItems[itemID].m_flags = flags;
1✔
497
}
1✔
498

499
/********************************************************************
500
 * 2D view background
501
 ********************************************************************/
502

503
QString MonitorProperties::customBackground(quint32 fid)
×
504
{
505
    return m_customBackgroundImages.value(fid, QString());
×
506
}
507

508
/*********************************************************************
509
 * Load & Save
510
 *********************************************************************/
511

512
bool MonitorProperties::loadXML(QXmlStreamReader &root, const Doc *mainDocument)
×
513
{
514
    if (root.name() != KXMLQLCMonitorProperties)
×
515
    {
516
        qWarning() << Q_FUNC_INFO << "Monitor node not found";
×
517
        return false;
×
518
    }
519

520
    QXmlStreamAttributes attrs = root.attributes();
×
521

522
    if (attrs.hasAttribute(KXMLQLCMonitorDisplay) == false)
×
523
    {
524
        qWarning() << Q_FUNC_INFO << "Cannot determine Monitor display mode !";
×
525
        return false;
×
526
    }
527

528
    setDisplayMode(DisplayMode(attrs.value(KXMLQLCMonitorDisplay).toString().toInt()));
×
529
    if (attrs.hasAttribute(KXMLQLCMonitorShowLabels))
×
530
    {
531
        if (attrs.value(KXMLQLCMonitorShowLabels).toString() == "1")
×
532
            setLabelsVisible(true);
×
533
        else
534
            setLabelsVisible(false);
×
535
    }
536

537
    while (root.readNextStartElement())
×
538
    {
539
        QXmlStreamAttributes tAttrs = root.attributes();
×
540
        if (root.name() == KXMLQLCMonitorFont)
×
541
        {
542
            QFont fn;
×
543
            fn.fromString(root.readElementText());
×
544
            setFont(fn);
×
545
        }
×
546
        else if (root.name() == KXMLQLCMonitorChannels)
×
547
            setChannelStyle(ChannelStyle(root.readElementText().toInt()));
×
548
        else if (root.name() == KXMLQLCMonitorValues)
×
549
            setValueStyle(ValueStyle(root.readElementText().toInt()));
×
550
        else if (root.name() == KXMLQLCMonitorCommonBackground)
×
551
            setCommonBackgroundImage(mainDocument->denormalizeComponentPath(root.readElementText()));
×
552
        else if (root.name() == KXMLQLCMonitorCustomBgItem)
×
553
        {
554
            if (tAttrs.hasAttribute(KXMLQLCMonitorItemID))
×
555
            {
556
                quint32 fid = tAttrs.value(KXMLQLCMonitorItemID).toString().toUInt();
×
557
                setCustomBackgroundItem(fid, mainDocument->denormalizeComponentPath(root.readElementText()));
×
558
            }
559
        }
560
        else if (root.name() == KXMLQLCMonitorGrid)
×
561
        {
562
            int w = 5, h = 3, d = 5;
×
563
            if (tAttrs.hasAttribute(KXMLQLCMonitorGridWidth))
×
564
                w = tAttrs.value(KXMLQLCMonitorGridWidth).toString().toInt();
×
565
            if (tAttrs.hasAttribute(KXMLQLCMonitorGridHeight))
×
566
                h = tAttrs.value(KXMLQLCMonitorGridHeight).toString().toInt();
×
567
            if (tAttrs.hasAttribute(KXMLQLCMonitorGridDepth))
×
568
                d = tAttrs.value(KXMLQLCMonitorGridDepth).toString().toInt();
×
569
            else
570
                d = h; // backward compatibility
×
571

572
            if (tAttrs.hasAttribute(KXMLQLCMonitorGridUnits))
×
573
                setGridUnits(GridUnits(tAttrs.value(KXMLQLCMonitorGridUnits).toString().toInt()));
×
574

575
            if (tAttrs.hasAttribute(KXMLQLCMonitorPointOfView))
×
576
                setPointOfView(PointOfView(tAttrs.value(KXMLQLCMonitorPointOfView).toString().toInt()));
×
577
            else
578
                setPointOfView(Undefined);
×
579

580
            setGridSize(QVector3D(w, h, d));
×
581
            root.skipCurrentElement();
×
582
        }
583
        else if (root.name() == KXMLQLCMonitorStageItem)
×
584
        {
585
            setStageType(StageType(root.readElementText().toInt()));
×
586
        }
587
        else if (root.name() == KXMLQLCMonitorFixtureItem)
×
588
        {
589
            // Fixture ID is mandatory. Skip the whole entry if not found.
590
            if (tAttrs.hasAttribute(KXMLQLCMonitorItemID) == false)
×
591
            {
592
                root.skipCurrentElement();
×
593
                continue;
×
594
            }
595

596
            PreviewItem item;
×
597
            quint32 fid = tAttrs.value(KXMLQLCMonitorItemID).toString().toUInt();
×
598
            quint16 headIndex = 0;
×
599
            quint16 linkedIndex = 0;
×
600
            QVector3D pos(0, 0, 0);
×
601
            QVector3D rot(0, 0, 0);
×
602

603
            item.m_flags = 0;
×
604
            item.m_zoom = 0;
×
605

606
            if (tAttrs.hasAttribute(KXMLQLCMonitorFixtureHeadIndex))
×
607
                headIndex = tAttrs.value(KXMLQLCMonitorFixtureHeadIndex).toString().toUInt();
×
608

609
            if (tAttrs.hasAttribute(KXMLQLCMonitorFixtureLinkedIndex))
×
610
            {
611
                linkedIndex = tAttrs.value(KXMLQLCMonitorFixtureLinkedIndex).toString().toUInt();
×
612

613
                if (tAttrs.hasAttribute(KXMLQLCMonitorItemName))
×
614
                    item.m_name = tAttrs.value(KXMLQLCMonitorItemName).toString();
×
615
            }
616

617
            if (tAttrs.hasAttribute(KXMLQLCMonitorItemXPosition))
×
618
                pos.setX(tAttrs.value(KXMLQLCMonitorItemXPosition).toString().toDouble());
×
619
            if (tAttrs.hasAttribute(KXMLQLCMonitorItemYPosition))
×
620
                pos.setY(tAttrs.value(KXMLQLCMonitorItemYPosition).toString().toDouble());
×
621
            if (tAttrs.hasAttribute(KXMLQLCMonitorItemZPosition))
×
622
                pos.setZ(tAttrs.value(KXMLQLCMonitorItemZPosition).toString().toDouble());
×
623
            item.m_position = pos;
×
624

625
            if (tAttrs.hasAttribute(KXMLQLCMonitorFixtureRotation)) // check legacy first
×
626
            {
627
                rot.setY(tAttrs.value(KXMLQLCMonitorFixtureRotation).toString().toDouble());
×
628
            }
629
            else
630
            {
631
                if (tAttrs.hasAttribute(KXMLQLCMonitorItemXRotation))
×
632
                    rot.setX(tAttrs.value(KXMLQLCMonitorItemXRotation).toString().toDouble());
×
633
                if (tAttrs.hasAttribute(KXMLQLCMonitorItemYRotation))
×
634
                    rot.setY(tAttrs.value(KXMLQLCMonitorItemYRotation).toString().toDouble());
×
635
                if (tAttrs.hasAttribute(KXMLQLCMonitorItemZRotation))
×
636
                    rot.setZ(tAttrs.value(KXMLQLCMonitorItemZRotation).toString().toDouble());
×
637
            }
638
            item.m_rotation = rot;
×
639

640
            if (tAttrs.hasAttribute(KXMLQLCMonitorFixtureGelColor))
×
641
                item.m_color = QColor(tAttrs.value(KXMLQLCMonitorFixtureGelColor).toString());
×
642

643
            if (tAttrs.hasAttribute(KXMLQLCMonitorFixtureFixedZoom))
×
644
                item.m_zoom = tAttrs.value(KXMLQLCMonitorFixtureFixedZoom).toString().toInt();
×
645

646
            if (tAttrs.hasAttribute(KXMLQLCMonitorFixtureHiddenFlag))
×
647
                item.m_flags |= HiddenFlag;
×
648
            if (tAttrs.hasAttribute(KXMLQLCMonitorFixtureInvPanFlag))
×
649
                item.m_flags |= InvertedPanFlag;
×
650
            if (tAttrs.hasAttribute(KXMLQLCMonitorFixtureInvTiltFlag))
×
651
                item.m_flags |= InvertedTiltFlag;
×
652

653
            setFixtureItem(fid, headIndex, linkedIndex, item);
×
654
            root.skipCurrentElement();
×
655

656
        }
×
657
        else if (root.name() == KXMLQLCMonitorMeshItem)
×
658
        {
659
            // Item ID is mandatory. Skip the whole entry if not found.
660
            if (tAttrs.hasAttribute(KXMLQLCMonitorItemID) == false)
×
661
            {
662
                root.skipCurrentElement();
×
663
                continue;
×
664
            }
665

666
            PreviewItem item;
×
667
            quint32 itemID = tAttrs.value(KXMLQLCMonitorItemID).toString().toUInt();
×
668
            QVector3D pos(0, 0, 0);
×
669
            QVector3D rot(0, 0, 0);
×
670
            QVector3D scale(1.0, 1.0, 1.0);
×
671

672
            item.m_flags = 0;
×
673

674
            if (tAttrs.hasAttribute(KXMLQLCMonitorItemXPosition))
×
675
                pos.setX(tAttrs.value(KXMLQLCMonitorItemXPosition).toString().toDouble());
×
676
            if (tAttrs.hasAttribute(KXMLQLCMonitorItemYPosition))
×
677
                pos.setY(tAttrs.value(KXMLQLCMonitorItemYPosition).toString().toDouble());
×
678
            if (tAttrs.hasAttribute(KXMLQLCMonitorItemZPosition))
×
679
                pos.setZ(tAttrs.value(KXMLQLCMonitorItemZPosition).toString().toDouble());
×
680
            item.m_position = pos;
×
681

682
            if (tAttrs.hasAttribute(KXMLQLCMonitorItemXRotation))
×
683
                rot.setX(tAttrs.value(KXMLQLCMonitorItemXRotation).toString().toDouble());
×
684
            if (tAttrs.hasAttribute(KXMLQLCMonitorItemYRotation))
×
685
                rot.setY(tAttrs.value(KXMLQLCMonitorItemYRotation).toString().toDouble());
×
686
            if (tAttrs.hasAttribute(KXMLQLCMonitorItemZRotation))
×
687
                rot.setZ(tAttrs.value(KXMLQLCMonitorItemZRotation).toString().toDouble());
×
688
            item.m_rotation = rot;
×
689

690
            if (tAttrs.hasAttribute(KXMLQLCMonitorItemXScale))
×
691
                scale.setX(tAttrs.value(KXMLQLCMonitorItemXScale).toString().toDouble());
×
692
            if (tAttrs.hasAttribute(KXMLQLCMonitorItemYScale))
×
693
                scale.setY(tAttrs.value(KXMLQLCMonitorItemYScale).toString().toDouble());
×
694
            if (tAttrs.hasAttribute(KXMLQLCMonitorItemZScale))
×
695
                scale.setZ(tAttrs.value(KXMLQLCMonitorItemZScale).toString().toDouble());
×
696
            item.m_scale = scale;
×
697

698
            if (tAttrs.hasAttribute(KXMLQLCMonitorFixtureHiddenFlag))
×
699
                item.m_flags |= HiddenFlag;
×
700

701
            if (tAttrs.hasAttribute(KXMLQLCMonitorItemRes))
×
702
                item.m_resource = tAttrs.value(KXMLQLCMonitorItemRes).toString();
×
703

704
            if (tAttrs.hasAttribute(KXMLQLCMonitorItemName))
×
705
                item.m_name = tAttrs.value(KXMLQLCMonitorItemName).toString();
×
706

707
            m_genericItems[itemID] = item;
×
708
            root.skipCurrentElement();
×
709
        }
×
710
        else
711
        {
712
            qWarning() << Q_FUNC_INFO << "Unknown MonitorProperties tag:" << root.name();
×
713
            root.skipCurrentElement();
×
714
        }
715
    }
×
716
    return true;
×
717
}
×
718

719
bool MonitorProperties::saveXML(QXmlStreamWriter *doc, const Doc *mainDocument) const
1✔
720
{
721
    Q_ASSERT(doc != NULL);
1✔
722

723
    /* Create the master Monitor node */
724
    doc->writeStartElement(KXMLQLCMonitorProperties);
2✔
725
    doc->writeAttribute(KXMLQLCMonitorDisplay, QString::number(displayMode()));
2✔
726
    doc->writeAttribute(KXMLQLCMonitorShowLabels, QString::number(labelsVisible()));
2✔
727

728
    /* Font */
729
    doc->writeTextElement(KXMLQLCMonitorFont, font().toString());
2✔
730
    /* Channels style */
731
    doc->writeTextElement(KXMLQLCMonitorChannels, QString::number(channelStyle()));
2✔
732
    /* Values style */
733
    doc->writeTextElement(KXMLQLCMonitorValues, QString::number(valueStyle()));
2✔
734

735
    /* Background */
736
    if (commonBackgroundImage().isEmpty() == false)
1✔
737
    {
738
        doc->writeTextElement(KXMLQLCMonitorCommonBackground,
×
739
                              mainDocument->normalizeComponentPath(commonBackgroundImage()));
×
740
    }
741
    else if (customBackgroundList().isEmpty() == false)
1✔
742
    {
743
        QMapIterator <quint32, QString> it(customBackgroundList());
×
744
        while (it.hasNext() == true)
×
745
        {
746
            it.next();
×
747
            doc->writeStartElement(KXMLQLCMonitorCustomBgItem);
×
748
            quint32 fid = it.key();
×
749
            doc->writeAttribute(KXMLQLCMonitorItemID, QString::number(fid));
×
750
            doc->writeCharacters(mainDocument->normalizeComponentPath(it.value()));
×
751
            doc->writeEndElement();
×
752
        }
753
    }
×
754

755
    doc->writeStartElement(KXMLQLCMonitorGrid);
2✔
756
    doc->writeAttribute(KXMLQLCMonitorGridWidth, QString::number(gridSize().x()));
2✔
757
    doc->writeAttribute(KXMLQLCMonitorGridHeight, QString::number(gridSize().y()));
2✔
758
    doc->writeAttribute(KXMLQLCMonitorGridDepth, QString::number(gridSize().z()));
2✔
759
    doc->writeAttribute(KXMLQLCMonitorGridUnits, QString::number(gridUnits()));
2✔
760
    if (m_pointOfView != Undefined)
1✔
761
        doc->writeAttribute(KXMLQLCMonitorPointOfView, QString::number(pointOfView()));
×
762

763
    doc->writeEndElement();
1✔
764

765
#ifdef QMLUI
766
    doc->writeTextElement(KXMLQLCMonitorStageItem, QString::number(stageType()));
767
#endif
768

769
    // ***********************************************************
770
    // *                write fixtures information               *
771
    // ***********************************************************
772

773
    foreach (quint32 fid, fixtureItemsID())
2✔
774
    {
775
        foreach (quint32 subID, fixtureIDList(fid))
×
776
        {
777
            quint16 headIndex = fixtureHeadIndex(subID);
×
778
            quint16 linkedIndex = fixtureLinkedIndex(subID);
×
779
            PreviewItem item = fixtureItem(fid, headIndex, linkedIndex);
×
780

781
            doc->writeStartElement(KXMLQLCMonitorFixtureItem);
×
782
            doc->writeAttribute(KXMLQLCMonitorItemID, QString::number(fid));
×
783

784
            if (headIndex)
×
785
                doc->writeAttribute(KXMLQLCMonitorFixtureHeadIndex, QString::number(headIndex));
×
786

787
            if (linkedIndex)
×
788
            {
789
                doc->writeAttribute(KXMLQLCMonitorFixtureLinkedIndex, QString::number(linkedIndex));
×
790
                if (item.m_name.isEmpty() == false)
×
791
                    doc->writeAttribute(KXMLQLCMonitorItemName, item.m_name);
×
792
            }
793

794
            // write flags, if present
795
            if (item.m_flags & HiddenFlag)
×
796
                doc->writeAttribute(KXMLQLCMonitorFixtureHiddenFlag, KXMLQLCTrue);
×
797
            if (item.m_flags & InvertedPanFlag)
×
798
                doc->writeAttribute(KXMLQLCMonitorFixtureInvPanFlag, KXMLQLCTrue);
×
799
            if (item.m_flags & InvertedTiltFlag)
×
800
                doc->writeAttribute(KXMLQLCMonitorFixtureInvTiltFlag, KXMLQLCTrue);
×
801

802
            // always write position
803
            doc->writeAttribute(KXMLQLCMonitorItemXPosition, QString::number(item.m_position.x()));
×
804
            doc->writeAttribute(KXMLQLCMonitorItemYPosition, QString::number(item.m_position.y()));
×
805

806
#ifdef QMLUI
807
            doc->writeAttribute(KXMLQLCMonitorItemZPosition, QString::number(item.m_position.z()));
808

809
            // write rotation, if set
810
            if (item.m_rotation.x() != 0)
811
                doc->writeAttribute(KXMLQLCMonitorItemXRotation, QString::number(item.m_rotation.x()));
812
            if (item.m_rotation.y() != 0)
813
                doc->writeAttribute(KXMLQLCMonitorItemYRotation, QString::number(item.m_rotation.y()));
814
            if (item.m_rotation.z() != 0)
815
                doc->writeAttribute(KXMLQLCMonitorItemZRotation, QString::number(item.m_rotation.z()));
816
#else
817
            if (item.m_rotation != QVector3D(0, 0, 0))
×
818
                doc->writeAttribute(KXMLQLCMonitorFixtureRotation, QString::number(item.m_rotation.y()));
×
819
#endif
820
            if (item.m_color.isValid())
×
821
                doc->writeAttribute(KXMLQLCMonitorFixtureGelColor, item.m_color.name());
×
822

823
            if (item.m_zoom > 0)
×
824
                doc->writeAttribute(KXMLQLCMonitorFixtureFixedZoom, QString::number(item.m_zoom));
×
825

826
            doc->writeEndElement();
×
827
        }
×
828
    }
1✔
829
#ifdef QMLUI
830
    QDir dir = QDir::cleanPath(QLCFile::systemDirectory(MESHESDIR).path());
831
    QString meshDirAbsPath = dir.absolutePath() + QDir::separator();
832
#endif
833

834
    // ***********************************************************
835
    // *             write generic items information             *
836
    // ***********************************************************
837
    QMapIterator<quint32, PreviewItem> it(m_genericItems);
1✔
838
    while (it.hasNext())
1✔
839
    {
840
        it.next();
×
841
        quint32 itemID = it.key();
×
842
        PreviewItem item = it.value();
×
843

844
        doc->writeStartElement(KXMLQLCMonitorMeshItem);
×
845
        doc->writeAttribute(KXMLQLCMonitorItemID, QString::number(itemID));
×
846

847
        // write flags, if present
848
        if (item.m_flags & HiddenFlag)
×
849
            doc->writeAttribute(KXMLQLCMonitorFixtureHiddenFlag, KXMLQLCTrue);
×
850

851
        // always write position
852
        doc->writeAttribute(KXMLQLCMonitorItemXPosition, QString::number(item.m_position.x()));
×
853
        doc->writeAttribute(KXMLQLCMonitorItemYPosition, QString::number(item.m_position.y()));
×
854
        doc->writeAttribute(KXMLQLCMonitorItemZPosition, QString::number(item.m_position.z()));
×
855

856
        // write rotation, if set
857
        if (item.m_rotation.x() != 0)
×
858
            doc->writeAttribute(KXMLQLCMonitorItemXRotation, QString::number(item.m_rotation.x()));
×
859
        if (item.m_rotation.y() != 0)
×
860
            doc->writeAttribute(KXMLQLCMonitorItemYRotation, QString::number(item.m_rotation.y()));
×
861
        if (item.m_rotation.z() != 0)
×
862
            doc->writeAttribute(KXMLQLCMonitorItemZRotation, QString::number(item.m_rotation.z()));
×
863

864
        // write scale, if set
865
        if (item.m_scale.x() != 1.0)
×
866
            doc->writeAttribute(KXMLQLCMonitorItemXScale, QString::number(item.m_scale.x()));
×
867
        if (item.m_scale.y() != 1.0)
×
868
            doc->writeAttribute(KXMLQLCMonitorItemYScale, QString::number(item.m_scale.y()));
×
869
        if (item.m_scale.z() != 1.0)
×
870
            doc->writeAttribute(KXMLQLCMonitorItemZScale, QString::number(item.m_scale.z()));
×
871

872
        if (item.m_resource.isEmpty() == false)
×
873
        {
874
            // perform normalization depending on the mesh location
875
            // (mesh folder, project path, absolute path)
876
            QFileInfo res(item.m_resource);
×
877

878
            if (res.isRelative())
×
879
            {
880
                doc->writeAttribute(KXMLQLCMonitorItemRes, item.m_resource);
×
881
            }
882
#ifdef QMLUI
883
            else if (item.m_resource.startsWith(meshDirAbsPath))
884
            {
885
                item.m_resource.remove(meshDirAbsPath);
886
                doc->writeAttribute(KXMLQLCMonitorItemRes, item.m_resource);
887
            }
888
#endif
889
            else
890
            {
891
                doc->writeAttribute(KXMLQLCMonitorItemRes, mainDocument->normalizeComponentPath(item.m_resource));
×
892
            }
893
        }
×
894

895
        if (item.m_name.isEmpty() == false)
×
896
            doc->writeAttribute(KXMLQLCMonitorItemName, item.m_name);
×
897

898
        doc->writeEndElement();
×
899
    }
×
900

901
    doc->writeEndElement();
1✔
902

903
    return true;
1✔
904
}
1✔
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