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

mcallegari / qlcplus / 13633248611

03 Mar 2025 02:31PM UTC coverage: 31.871% (+0.4%) from 31.5%
13633248611

push

github

web-flow
actions: add chrpath to profile

14689 of 46089 relevant lines covered (31.87%)

26426.11 hits per line

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

17.88
/engine/src/channelsgroup.cpp
1
/*
2
  Q Light Controller
3
  channelsgroup.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

24
#include "qlcfixturemode.h"
25
#include "channelsgroup.h"
26
#include "scenevalue.h"
27
#include "fixture.h"
28
#include "doc.h"
29

30
#define KXMLQLCChannelsGroupID    "ID"
31
#define KXMLQLCChannelsGroupName  "Name"
32
#define KXMLQLCChannelsGroupValue "Value"
33

34
#define KXMLQLCChannelsGroupInputUniverse "InputUniverse"
35
#define KXMLQLCChannelsGroupInputChannel  "InputChannel"
36

37

38
ChannelsGroup::ChannelsGroup(Doc* doc)
4✔
39
    : QObject(doc)
40
    , m_id(ChannelsGroup::invalidId())
8✔
41
    , m_masterValue(0)
4✔
42
{
43
    setName(tr("New Group"));
4✔
44
    m_doc = doc;
4✔
45

46
    init();
4✔
47
}
4✔
48

49
ChannelsGroup::ChannelsGroup(Doc* doc, const ChannelsGroup* chg)
×
50
    : QObject(doc)
51
    , m_doc(doc)
×
52
    , m_id(chg->id())
×
53
    , m_name(chg->name())
×
54
    , m_masterValue(0)
×
55
    , m_channels(chg->getChannels())
×
56
    , m_input(chg->inputSource())
×
57
{
58
    init();
×
59
}
×
60

61
ChannelsGroup::~ChannelsGroup()
8✔
62
{
63
}
8✔
64

65
void ChannelsGroup::init()
4✔
66
{
67
    connect(m_doc, SIGNAL(fixtureRemoved(quint32)),
4✔
68
            this, SLOT(slotFixtureRemoved(quint32)));
69
}
4✔
70

71
void ChannelsGroup::slotFixtureRemoved(quint32 fixtureId)
×
72
{
73
    bool hasChanged = false;
74

75
    QMutableListIterator<SceneValue> channelsIt(m_channels);
×
76
    while (channelsIt.hasNext())
×
77
    {
78
        SceneValue scv(channelsIt.next());
×
79
        if (scv.fxi == fixtureId)
×
80
        {
81
            channelsIt.remove();
×
82
            hasChanged = true;
83
        }
84
    }
×
85

86
    if (hasChanged)
×
87
        emit changed(this->id());
×
88
}
×
89

90
/****************************************************************************
91
 * ID
92
 ****************************************************************************/
93

94
void ChannelsGroup::setId(quint32 id)
4✔
95
{
96
    m_id = id;
4✔
97
}
4✔
98

99
quint32 ChannelsGroup::id() const
18✔
100
{
101
    return m_id;
18✔
102
}
103

104
quint32 ChannelsGroup::invalidId()
19✔
105
{
106
    return UINT_MAX;
19✔
107
}
108

109
/****************************************************************************
110
 * Name
111
 ****************************************************************************/
112

113
void ChannelsGroup::setName(const QString& name)
4✔
114
{
115
    m_name = name;
4✔
116
    emit changed(this->id());
4✔
117
}
4✔
118

119
QString ChannelsGroup::name() const
×
120
{
121
    return m_name;
×
122
}
123

124
/************************************************************************
125
 * Channels
126
 ************************************************************************/
127

128
void ChannelsGroup::resetChannels()
×
129
{
130
    m_channels.clear();
×
131
}
×
132

133
bool ChannelsGroup::addChannel(quint32 fxid, quint32 channel)
3✔
134
{
135
    if (fxid == invalidId())
3✔
136
        return false;
137

138
    m_channels.append(SceneValue(fxid, channel, 0));
3✔
139

140
    return true;
3✔
141
}
142

143

144
QList <SceneValue> ChannelsGroup::getChannels() const
×
145
{
146
    return m_channels;
×
147
}
148

149
/*********************************************************************
150
 * Status
151
 *********************************************************************/
152
QString ChannelsGroup::status(Doc *doc) const
×
153
{
154
    QString info;
155

156
    QString title("<TR><TD CLASS='hilite' COLSPAN='3'><CENTER>%1</CENTER></TD></TR>");
×
157
    info += "<TABLE COLS='3' WIDTH='100%'>";
×
158

159
    // Fixture title
160
    info += title.arg(name());
×
161

162
    /********************************************************************
163
     * Channels
164
     ********************************************************************/
165

166
    // Title row
167
    info += QString("<TR><TD CLASS='subhi'>%1</TD>").arg(tr("Fixture"));
×
168
    info += QString("<TD CLASS='subhi'>%1</TD>").arg(tr("Channel"));
×
169
    info += QString("<TD CLASS='subhi'>%1</TD></TR>").arg(tr("Description"));
×
170

171
    foreach (SceneValue value, m_channels)
×
172
    {
173
        Fixture *fixture = doc->fixture(value.fxi);
×
174
        if (fixture == NULL)
×
175
            return QString();
×
176
        const QLCFixtureMode *mode = fixture->fixtureMode();
×
177
        QString chInfo("<TR><TD>%1</TD><TD>%2</TD><TD>%3</TD></TR>");
×
178
        if (mode != NULL)
×
179
        {
180
            info += chInfo.arg(fixture->name()).arg(value.channel + 1)
×
181
                .arg(mode->channels().at(value.channel)->name());
×
182
        }
183
        else
184
        {
185
            info += chInfo.arg(fixture->name()).arg(value.channel + 1)
×
186
                .arg(QString(tr("Channel %1")).arg(value.channel));
×
187
        }
188
    }
×
189

190
    // HTML document & table closure
191
    info += "</TABLE>";
×
192

193
    return info;
194
}
×
195

196
/*********************************************************************
197
 * External input
198
 *********************************************************************/
199
void ChannelsGroup::setInputSource(QSharedPointer<QLCInputSource> const& source)
×
200
{
201
    if (!m_input.isNull() && m_input->isValid())
×
202
        disconnect(m_doc->inputOutputMap(), SIGNAL(inputValueChanged(quint32,quint32,uchar)),
×
203
                this, SLOT(slotInputValueChanged(quint32,quint32,uchar)));
204

205
    m_input = source;
×
206

207
    // Connect when the first valid input source is set
208
    if (!source.isNull() && source->isValid())
×
209
        connect(m_doc->inputOutputMap(), SIGNAL(inputValueChanged(quint32,quint32,uchar)),
×
210
                this, SLOT(slotInputValueChanged(quint32,quint32,uchar)));
211
}
×
212

213
QSharedPointer<QLCInputSource> const& ChannelsGroup::inputSource() const
×
214
{
215
    return m_input;
×
216
}
217

218
void ChannelsGroup::slotInputValueChanged(quint32 universe, quint32 channel, uchar value)
×
219
{
220
    Q_UNUSED(value);
221

222
    /* Don't let input data thru in operate mode */
223
    if (m_doc->mode() == Doc::Operate)
×
224
        return;
225

226
    //qDebug() << Q_FUNC_INFO << "universe: " << universe << ", channel: " << channel << ", value: " << value;
227

228
    if (inputSource() != NULL &&
×
229
        inputSource()->universe() == universe &&
×
230
        inputSource()->channel() == channel)
×
231
    {
232
        emit valueChanged(channel, value);
×
233
    }
234
}
235

236
/*****************************************************************************
237
 * Load & Save
238
 *****************************************************************************/
239
bool ChannelsGroup::loader(QXmlStreamReader &xmlDoc, Doc* doc)
×
240
{
241
    bool result = false;
242

243
    ChannelsGroup* grp = new ChannelsGroup(doc);
×
244
    Q_ASSERT(grp != NULL);
245

246
    if (grp->loadXML(xmlDoc) == true)
×
247
    {
248
        doc->addChannelsGroup(grp, grp->id());
×
249
        result = true;
250
    }
251
    else
252
    {
253
        qWarning() << Q_FUNC_INFO << "ChannelsGroup" << grp->name() << "cannot be loaded.";
×
254
        delete grp;
×
255
        result = false;
256
    }
257

258
    return result;
×
259
}
260

261
bool ChannelsGroup::saveXML(QXmlStreamWriter *doc)
×
262
{
263
    Q_ASSERT(doc != NULL);
264

265
    QString str;
266
    foreach (SceneValue value, this->getChannels())
×
267
    {
268
        if (str.isEmpty() == false)
×
269
            str.append(",");
×
270
        str.append(QString("%1,%2").arg(value.fxi).arg(value.channel));
×
271
    }
×
272

273
    /* Channels Group entry */
274
    doc->writeStartElement(KXMLQLCChannelsGroup);
×
275
    doc->writeAttribute(KXMLQLCChannelsGroupID, QString::number(this->id()));
×
276
    doc->writeAttribute(KXMLQLCChannelsGroupName, this->name());
×
277
    doc->writeAttribute(KXMLQLCChannelsGroupValue, QString::number(m_masterValue));
×
278

279
    if (!m_input.isNull() && m_input->isValid())
×
280
    {
281
        doc->writeAttribute(KXMLQLCChannelsGroupInputUniverse,QString("%1").arg(m_input->universe()));
×
282
        doc->writeAttribute(KXMLQLCChannelsGroupInputChannel, QString("%1").arg(m_input->channel()));
×
283
    }
284
    if (str.isEmpty() == false)
×
285
        doc->writeCharacters(str);
×
286

287
    doc->writeEndElement();
×
288

289
    return true;
×
290
}
×
291

292
bool ChannelsGroup::loadXML(QXmlStreamReader &xmlDoc)
×
293
{
294
    if (xmlDoc.name() != KXMLQLCChannelsGroup)
×
295
    {
296
        qWarning() << Q_FUNC_INFO << "Channels group node not found";
×
297
        return false;
×
298
    }
299

300
    QXmlStreamAttributes attrs = xmlDoc.attributes();
×
301

302
    bool ok = false;
×
303
    quint32 id = attrs.value(KXMLQLCChannelsGroupID).toString().toUInt(&ok);
×
304
    if (ok == false)
×
305
    {
306
        qWarning() << "Invalid ChannelsGroup ID:" << attrs.value(KXMLQLCChannelsGroupID).toString();
×
307
        return false;
×
308
    }
309

310
    // Assign the ID to myself
311
    m_id = id;
×
312

313
    if (attrs.hasAttribute(KXMLQLCChannelsGroupName) == true)
×
314
        m_name = attrs.value(KXMLQLCChannelsGroupName).toString();
×
315
    if (attrs.hasAttribute(KXMLQLCChannelsGroupValue) == true)
×
316
        m_masterValue = uchar(attrs.value(KXMLQLCChannelsGroupValue).toString().toInt());
×
317

318
    QString chansValues = xmlDoc.readElementText();
×
319
    if (chansValues.isEmpty() == false)
×
320
    {
321
        QStringList varray = chansValues.split(",");
×
322
        for (int i = 0; i < varray.count(); i+=2)
×
323
        {
324
            SceneValue scv(QString(varray.at(i)).toUInt(),
×
325
                           QString(varray.at(i + 1)).toUInt(), 0);
×
326
            Fixture* fxi = m_doc->fixture(scv.fxi);
×
327
            if (fxi == NULL)
×
328
            {
329
                qWarning() << Q_FUNC_INFO << "Fixture not present:" << scv.fxi;
×
330
                continue;
×
331
            }
332
            const QLCChannel* ch = fxi->channel(scv.channel);
×
333
            if (ch == NULL)
×
334
            {
335
                qWarning() << Q_FUNC_INFO << "Fixture" << scv.fxi << "does not have channel" << scv.channel;
×
336
                continue;
×
337
            }
338
            m_channels.append(scv);
×
339
        }
×
340
    }
341

342
    if (attrs.hasAttribute(KXMLQLCChannelsGroupInputUniverse) == true &&
×
343
        attrs.hasAttribute(KXMLQLCChannelsGroupInputChannel) == true)
×
344
    {
345
        quint32 uni = attrs.value(KXMLQLCChannelsGroupInputUniverse).toString().toInt();
×
346
        quint32 ch = attrs.value(KXMLQLCChannelsGroupInputChannel).toString().toInt();
×
347
        setInputSource(QSharedPointer<QLCInputSource>(new QLCInputSource(uni, ch)));
×
348
    }
349

350
    return true;
351
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc