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

mcallegari / qlcplus / 20710371529

05 Jan 2026 09:06AM UTC coverage: 34.17% (-0.09%) from 34.256%
20710371529

Pull #1865

github

web-flow
Merge 63a0ef496 into f926bbb3a
Pull Request #1865: New Fixtures for 6 ProLights devices

17716 of 51846 relevant lines covered (34.17%)

19737.47 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

410
    // always add the basic fixture item ID
411
    list.append(0);
×
412

413
    if (m_fixtureItems.contains(fid) == false)
×
414
        return list;
×
415

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

419
    return list;
×
420
}
×
421

422
/********************************************************************
423
 * Generic items
424
 ********************************************************************/
425

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

673
            item.m_flags = 0;
×
674

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

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

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

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

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

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

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

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

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

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

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

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

764
    doc->writeEndElement();
1✔
765

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

902
    doc->writeEndElement();
1✔
903

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