• 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

0.0
/engine/src/show.cpp
1
/*
2
  Q Light Controller Plus
3
  show.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 <QString>
23
#include <QDebug>
24
#include <QFile>
25
#include <QList>
26

27
#include "showrunner.h"
28
#include "function.h"
29
#include "show.h"
30
#include "doc.h"
31

32
#define KXMLQLCShowTimeDivision QString("TimeDivision")
33
#define KXMLQLCShowTimeType     QString("Type")
34
#define KXMLQLCShowTimeBPM      QString("BPM")
35

36
/*****************************************************************************
37
 * Initialization
38
 *****************************************************************************/
39

40
Show::Show(Doc* doc) : Function(doc, Function::ShowType)
×
41
  , m_timeDivType(QString("Time"))
42
  , m_timeDivBPM(120)
43
  , m_latestTrackId(0)
44
  , m_runner(NULL)
×
45
{
46
    setName(tr("New Show"));
×
47

48
    // Clear attributes here. I want attributes to be mapped
49
    // exactly like the Show tracks
50
    unregisterAttribute(tr("Intensity"));
×
51
}
×
52

53
Show::~Show()
×
54
{
55
    m_tracks.clear();
×
56
}
×
57

58
QIcon Show::getIcon() const
×
59
{
60
    return QIcon(":/show.png");
×
61
}
62

63
quint32 Show::totalDuration()
×
64
{
65
    quint32 totalDuration = 0;
×
66

67
    foreach(Track *track, tracks())
×
68
    {
69
        foreach(ShowFunction *sf, track->showFunctions())
×
70
        {
71
            if (sf->startTime() + sf->duration(doc()) > totalDuration)
×
72
                totalDuration = sf->startTime() + sf->duration(doc());
×
73
        }
74
    }
75

76
    return totalDuration;
×
77
}
78

79
/*****************************************************************************
80
 * Copying
81
 *****************************************************************************/
82

83
Function* Show::createCopy(Doc* doc, bool addToDoc)
×
84
{
85
    Q_ASSERT(doc != NULL);
×
86

87
    Function* copy = new Show(doc);
×
88
    if (copy->copyFrom(this) == false)
×
89
    {
90
        delete copy;
×
91
        copy = NULL;
×
92
    }
93
    if (addToDoc == true && doc->addFunction(copy) == false)
×
94
    {
95
        delete copy;
×
96
        copy = NULL;
×
97
    }
98

99
    return copy;
×
100
}
101

102
bool Show::copyFrom(const Function* function)
×
103
{
104
    const Show* show = qobject_cast<const Show*> (function);
×
105
    if (show == NULL)
×
106
        return false;
×
107

108
    m_timeDivType = show->m_timeDivType;
×
109
    m_timeDivBPM = show->m_timeDivBPM;
×
110
    m_latestTrackId = show->m_latestTrackId;
×
111

112
    // create a copy of each track
113
    foreach(Track *track, show->tracks())
×
114
    {
115
        quint32 sceneID = track->getSceneID();
×
116
        Track* newTrack = new Track(sceneID);
×
117
        newTrack->setName(track->name());
×
118
        addTrack(newTrack);
×
119

120
        // create a copy of each sequence/audio in a track
121
        foreach(ShowFunction *sfunc, track->showFunctions())
×
122
        {
123
            Function* function = doc()->function(sfunc->functionID());
×
124
            if (function == NULL)
×
125
                continue;
×
126

127
            /* Attempt to create a copy of the function to Doc */
128
            Function* copy = function->createCopy(doc());
×
129
            if (copy != NULL)
×
130
            {
131
                copy->setName(tr("Copy of %1").arg(function->name()));
×
132
                ShowFunction *showFunc = newTrack->createShowFunction(copy->id());
×
133
                showFunc->setStartTime(sfunc->startTime());
×
134
                showFunc->setDuration(sfunc->duration());
×
135
                showFunc->setColor(sfunc->color());
×
136
                showFunc->setLocked(sfunc->isLocked());
×
137
            }
138
        }
139
    }
140

141
    return Function::copyFrom(function);
×
142
}
143

144
/*********************************************************************
145
 * Time division
146
 *********************************************************************/
147

148
void Show::setTimeDivision(QString type, int BPM)
×
149
{
150
    qDebug() << "[setTimeDivision] type:" << type << ", BPM:" << BPM;
×
151
    m_timeDivType = type;
×
152
    m_timeDivBPM = BPM;
×
153
}
×
154

155
QString Show::getTimeDivisionType()
×
156
{
157
    return m_timeDivType;
×
158
}
159

160
int Show::getTimeDivisionBPM()
×
161
{
162
    return m_timeDivBPM;
×
163
}
164

165
/*****************************************************************************
166
 * Tracks
167
 *****************************************************************************/
168

169
bool Show::addTrack(Track *track, quint32 id)
×
170
{
171
    Q_ASSERT(track != NULL);
×
172

173
    // No ID given, this method can assign one
174
    if (id == Track::invalidId())
×
175
        id = createTrackId();
×
176

177
     track->setId(id);
×
178
     track->setShowId(this->id());
×
179
     m_tracks[id] = track;
×
180

181
     registerAttribute(track->name());
×
182

183
     return true;
×
184
}
185

186
bool Show::removeTrack(quint32 id)
×
187
{
188
    if (m_tracks.contains(id) == true)
×
189
    {
190
        Track* trk = m_tracks.take(id);
×
191
        Q_ASSERT(trk != NULL);
×
192

193
        unregisterAttribute(trk->name());
×
194

195
        //emit trackRemoved(id);
196
        delete trk;
×
197

198
        return true;
×
199
    }
200
    else
201
    {
202
        qWarning() << Q_FUNC_INFO << "No track found with id" << id;
×
203
        return false;
×
204
    }
205
}
206

207
Track* Show::track(quint32 id) const
×
208
{
209
    if (m_tracks.contains(id) == true)
×
210
        return m_tracks[id];
×
211
    else
212
        return NULL;
×
213
}
214

215
Track* Show::getTrackFromSceneID(quint32 id)
×
216
{
217
    foreach(Track *track, m_tracks)
×
218
    {
219
        if (track->getSceneID() == id)
×
220
            return track;
×
221
    }
222
    return NULL;
×
223
}
224

225
int Show::getTracksCount()
×
226
{
227
    return m_tracks.size();
×
228
}
229

230
void Show::moveTrack(Track *track, int direction)
×
231
{
232
    if (track == NULL)
×
233
        return;
×
234

235
    qint32 trkID = track->id();
×
236
    if (trkID == 0 && direction == -1)
×
237
        return;
×
238
    qint32 maxID = -1;
×
239
    Track *swapTrack = NULL;
×
240
    qint32 swapID = -1;
×
241
    if (direction > 0) swapID = INT_MAX;
×
242

243
    foreach(quint32 id, m_tracks.keys())
×
244
    {
245
        qint32 signedID = (qint32)id;
×
246
        if (signedID > maxID) maxID = signedID;
×
247
        if (direction == -1 && signedID > swapID && signedID < trkID)
×
248
            swapID = signedID;
×
249
        else if (direction == 1 && signedID < swapID && signedID > trkID)
×
250
            swapID = signedID;
×
251
    }
252

253
    qDebug() << Q_FUNC_INFO << "Direction:" << direction << ", trackID:" << trkID << ", swapID:" << swapID;
×
254
    if (swapID == trkID || (direction > 0 && trkID == maxID))
×
255
        return;
×
256

257
    swapTrack = m_tracks[swapID];
×
258
    m_tracks[swapID] = track;
×
259
    m_tracks[trkID] = swapTrack;
×
260
    track->setId(swapID);
×
261
    swapTrack->setId(trkID);
×
262
}
263

264
QList <Track*> Show::tracks() const
×
265
{
266
    return m_tracks.values();
×
267
}
268

269
quint32 Show::createTrackId()
×
270
{
271
    while (m_tracks.contains(m_latestTrackId) == true ||
×
272
           m_latestTrackId == Track::invalidId())
×
273
    {
274
        m_latestTrackId++;
×
275
    }
276

277
    return m_latestTrackId;
×
278
}
279

280
/*****************************************************************************
281
 * Load & Save
282
 *****************************************************************************/
283

284
bool Show::saveXML(QXmlStreamWriter *doc)
×
285
{
286
    Q_ASSERT(doc != NULL);
×
287

288
    /* Function tag */
289
    doc->writeStartElement(KXMLQLCFunction);
×
290

291
    /* Common attributes */
292
    saveXMLCommon(doc);
×
293

294
    doc->writeStartElement(KXMLQLCShowTimeDivision);
×
295
    doc->writeAttribute(KXMLQLCShowTimeType, m_timeDivType);
×
296
    doc->writeAttribute(KXMLQLCShowTimeBPM, QString::number(m_timeDivBPM));
×
297
    doc->writeEndElement();
×
298

299
    foreach(Track *track, m_tracks)
×
300
        track->saveXML(doc);
×
301

302
    /* End the <Function> tag */
303
    doc->writeEndElement();
×
304

305
    return true;
×
306
}
307

308
bool Show::loadXML(QXmlStreamReader &root)
×
309
{
310
    if (root.name() != KXMLQLCFunction)
×
311
    {
312
        qWarning() << Q_FUNC_INFO << "Function node not found";
×
313
        return false;
×
314
    }
315

316
    if (root.attributes().value(KXMLQLCFunctionType).toString() != typeToString(Function::ShowType))
×
317
    {
318
        qWarning() << Q_FUNC_INFO << root.attributes().value(KXMLQLCFunctionType).toString()
×
319
                   << "is not a show";
×
320
        return false;
×
321
    }
322

323
    while (root.readNextStartElement())
×
324
    {
325
        if (root.name() == KXMLQLCShowTimeDivision)
×
326
        {
327
            QString type = root.attributes().value(KXMLQLCShowTimeType).toString();
×
328
            int bpm = root.attributes().value(KXMLQLCShowTimeBPM).toString().toInt();
×
329
            setTimeDivision(type, bpm);
×
330
            root.skipCurrentElement();
×
331
        }
332
        else if (root.name() == KXMLQLCTrack)
×
333
        {
334
            Track *trk = new Track();
×
335
            if (trk->loadXML(root) == true)
×
336
                addTrack(trk, trk->id());
×
337
        }
338
        else
339
        {
340
            qWarning() << Q_FUNC_INFO << "Unknown Show tag:" << root.name();
×
341
            root.skipCurrentElement();
×
342
        }
343
    }
344

345
    return true;
×
346
}
347

348
void Show::postLoad()
×
349
{
350
    foreach (Track* track, m_tracks)
×
351
    {
352
        if (track->postLoad(doc()))
×
353
            doc()->setModified();
×
354
    }
355
}
×
356

357
bool Show::contains(quint32 functionId)
×
358
{
359
    Doc *doc = this->doc();
×
360
    Q_ASSERT(doc != NULL);
×
361

362
    if (functionId == id())
×
363
        return true;
×
364

365
    foreach (Track* track, m_tracks)
×
366
    {
367
        if (track->contains(doc, functionId))
×
368
            return true;
×
369
    }
370

371
    return false;
×
372
}
373

374
QList<quint32> Show::components()
×
375
{
376
    QList<quint32> ids;
×
377

378
    foreach (Track* track, m_tracks)
×
379
        ids.append(track->components());
×
380

381
    return ids;
×
382
}
383

384
/*****************************************************************************
385
 * Running
386
 *****************************************************************************/
387

388
void Show::preRun(MasterTimer* timer)
×
389
{
390
    Function::preRun(timer);
×
391
    m_runningChildren.clear();
×
392
    if (m_runner != NULL)
×
393
    {
394
        m_runner->stop();
×
395
        delete m_runner;
×
396
    }
397

398
    m_runner = new ShowRunner(doc(), this->id(), elapsed());
×
399
    int i = 0;
×
400
    foreach(Track *track, m_tracks.values())
×
401
        m_runner->adjustIntensity(getAttributeValue(i++), track);
×
402

403
    connect(m_runner, SIGNAL(timeChanged(quint32)), this, SIGNAL(timeChanged(quint32)));
×
404
    connect(m_runner, SIGNAL(showFinished()), this, SIGNAL(showFinished()));
×
405
    m_runner->start();
×
406
}
×
407

408
void Show::setPause(bool enable)
×
409
{
410
    if (m_runner != NULL)
×
411
        m_runner->setPause(enable);
×
412
    Function::setPause(enable);
×
413
}
×
414

415
void Show::write(MasterTimer* timer, QList<Universe *> universes)
×
416
{
417
    Q_UNUSED(universes);
418
    Q_UNUSED(timer);
419

420
    if (isPaused())
×
421
        return;
×
422

423
    m_runner->write();
×
424
}
425

426
void Show::postRun(MasterTimer* timer, QList<Universe *> universes)
×
427
{
428
    if (m_runner != NULL)
×
429
    {
430
        m_runner->stop();
×
431
        delete m_runner;
×
432
        m_runner = NULL;
×
433
    }
434
    Function::postRun(timer, universes);
×
435
}
×
436

437
void Show::slotChildStopped(quint32 fid)
×
438
{
439
    Q_UNUSED(fid);
440
}
×
441

442
/*****************************************************************************
443
 * Attributes
444
 *****************************************************************************/
445

446
int Show::adjustAttribute(qreal fraction, int attributeId)
×
447
{
448
    int attrIndex = Function::adjustAttribute(fraction, attributeId);
×
449

450
    if (m_runner != NULL)
×
451
    {
452
        QList<Track*> trkList = m_tracks.values();
×
453
        if (trkList.isEmpty() == false &&
×
454
            attrIndex >= 0 && attrIndex < trkList.count())
×
455
        {
456
            Track *track = trkList.at(attrIndex);
×
457
            if (track != NULL)
×
458
                m_runner->adjustIntensity(getAttributeValue(attrIndex), track);
×
459
        }
460
    }
461

462
    return attrIndex;
×
463
}
464

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