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

mcallegari / qlcplus / 6567093872

18 Oct 2023 10:04PM UTC coverage: 28.038% (-0.02%) from 28.056%
6567093872

push

github

mcallegari
qmlui: fix qmake build

15332 of 54682 relevant lines covered (28.04%)

20313.58 hits per line

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

75.36
/engine/src/qlcinputprofile.cpp
1
/*
2
  Q Light Controller
3
  qlcinputprofile.cpp
4

5
  Copyright (c) Heikki Junnila
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 <QMap>
25

26
#include "qlcinputchannel.h"
27
#include "qlcinputprofile.h"
28
#include "qlcchannel.h"
29
#include "qlcfile.h"
30

31
#define KXMLQLCInputProfileTypeMidi "MIDI"
32
#define KXMLQLCInputProfileTypeOs2l "OS2L"
33
#define KXMLQLCInputProfileTypeOsc "OSC"
34
#define KXMLQLCInputProfileTypeHid "HID"
35
#define KXMLQLCInputProfileTypeDmx "DMX"
36
#define KXMLQLCInputProfileTypeEnttec "Enttec"
37

38

39
/****************************************************************************
40
 * Initialization
41
 ****************************************************************************/
42

43
QLCInputProfile::QLCInputProfile()
123✔
44
    : m_manufacturer(QString())
45
    , m_model(QString())
46
    , m_path(QString())
47
    , m_type(MIDI)
48
    , m_midiSendNoteOff(true)
123✔
49
{
50
}
123✔
51

52
QLCInputProfile::QLCInputProfile(const QLCInputProfile& profile)
1✔
53
{
54
    *this = profile;
1✔
55
}
1✔
56

57
QLCInputProfile::~QLCInputProfile()
90✔
58
{
59
    destroyChannels();
54✔
60
}
90✔
61

62
QLCInputProfile *QLCInputProfile::createCopy()
×
63
{
64
    QLCInputProfile *copy = new QLCInputProfile();
×
65
    copy->setManufacturer(this->manufacturer());
×
66
    copy->setModel(this->model());
×
67
    copy->setType(this->type());
×
68
    copy->setPath(this->path());
×
69
    copy->setMidiSendNoteOff(this->midiSendNoteOff());
×
70

71
    /* Copy the other profile's channels */
72
    QMapIterator <quint32,QLCInputChannel*> it(this->channels());
×
73
    while (it.hasNext() == true)
×
74
    {
75
        it.next();
×
76
        copy->insertChannel(it.key(), it.value()->createCopy());
×
77
    }
78

79
    return copy;
×
80
}
81

82
QLCInputProfile& QLCInputProfile::operator=(const QLCInputProfile& profile)
2✔
83
{
84
    if (this != &profile)
2✔
85
    {
86
        /* Copy basic properties */
87
        m_manufacturer = profile.m_manufacturer;
2✔
88
        m_model = profile.m_model;
2✔
89
        m_path = profile.m_path;
2✔
90
        m_type = profile.m_type;
2✔
91
        m_midiSendNoteOff = profile.m_midiSendNoteOff;
2✔
92
        m_globalSettingsMap = profile.m_globalSettingsMap;
2✔
93

94
        /* Destroy all existing channels */
95
        destroyChannels();
2✔
96

97
        /* Copy the other profile's channels */
98
        QMapIterator <quint32,QLCInputChannel*> it(profile.m_channels);
4✔
99
        while (it.hasNext() == true)
10✔
100
        {
101
            it.next();
8✔
102
            insertChannel(it.key(), it.value()->createCopy());
8✔
103
        }
104
    }
105

106
    return *this;
2✔
107
}
108

109
/****************************************************************************
110
 * profile information
111
 ****************************************************************************/
112

113
void QLCInputProfile::setManufacturer(const QString& manufacturer)
116✔
114
{
115
    m_manufacturer = manufacturer;
116✔
116
}
116✔
117

118
QString QLCInputProfile::manufacturer() const
6✔
119
{
120
    return m_manufacturer;
6✔
121
}
122

123
void QLCInputProfile::setModel(const QString& model)
112✔
124
{
125
    m_model = model;
112✔
126
}
112✔
127

128
QString QLCInputProfile::model() const
6✔
129
{
130
    return m_model;
6✔
131
}
132

133
QString QLCInputProfile::name() const
1,975✔
134
{
135
    return QString("%1 %2").arg(m_manufacturer).arg(m_model);
1,975✔
136
}
137

138
void QLCInputProfile::setPath(QString path)
×
139
{
140
    m_path = path;
×
141
}
×
142

143
QString QLCInputProfile::path() const
1✔
144
{
145
    return m_path;
1✔
146
}
147

148
void QLCInputProfile::setType(QLCInputProfile::Type type)
104✔
149
{
150
    m_type = type;
104✔
151
}
104✔
152

153
QLCInputProfile::Type QLCInputProfile::type() const
×
154
{
155
    return m_type;
×
156
}
157

158
QString QLCInputProfile::typeToString(Type type)
1✔
159
{
160
    switch (type)
1✔
161
    {
162
    case MIDI:
1✔
163
        return KXMLQLCInputProfileTypeMidi;
1✔
164
    case OS2L:
×
165
        return KXMLQLCInputProfileTypeOs2l;
×
166
    case OSC:
×
167
        return KXMLQLCInputProfileTypeOsc;
×
168
    case HID:
×
169
        return KXMLQLCInputProfileTypeHid;
×
170
    case DMX:
×
171
        return KXMLQLCInputProfileTypeDmx;
×
172
    case Enttec:
×
173
        return KXMLQLCInputProfileTypeEnttec;
×
174
    default:
×
175
        return QString();
×
176
    }
177
}
178

179
QLCInputProfile::Type QLCInputProfile::stringToType(const QString& str)
104✔
180
{
181
    if (str == KXMLQLCInputProfileTypeMidi)
104✔
182
        return MIDI;
86✔
183
    else if (str == KXMLQLCInputProfileTypeOs2l)
18✔
184
        return OS2L;
×
185
    else if (str == KXMLQLCInputProfileTypeOsc)
18✔
186
        return OSC;
9✔
187
    else if (str == KXMLQLCInputProfileTypeHid)
9✔
188
        return HID;
3✔
189
    else if (str == KXMLQLCInputProfileTypeDmx)
6✔
190
        return DMX;
×
191
    else // if (str == KXMLQLCInputProfileTypeEnttec)
192
        return Enttec;
6✔
193
}
194

195
QList<QLCInputProfile::Type> QLCInputProfile::types()
×
196
{
197
    QList<Type> result;
×
198
    result
199
        << MIDI
×
200
        << OS2L
×
201
        << OSC
×
202
        << HID
×
203
        << DMX
×
204
        << Enttec;
×
205
    return result;
×
206
}
207

208
/********************************************************************
209
 * Plugin-specific global settings
210
 ********************************************************************/
211

212
void QLCInputProfile::setMidiSendNoteOff(bool enable)
15✔
213
{
214
    m_midiSendNoteOff = enable;
15✔
215
    m_globalSettingsMap["MIDISendNoteOff"] = QVariant(enable);
15✔
216
}
15✔
217

218
bool QLCInputProfile::midiSendNoteOff() const
1✔
219
{
220
    return m_midiSendNoteOff;
1✔
221
}
222

223
QMap<QString, QVariant> QLCInputProfile::globalSettings() const
5✔
224
{
225
    return m_globalSettingsMap;
5✔
226
}
227

228
/****************************************************************************
229
 * Channels
230
 ****************************************************************************/
231

232
bool QLCInputProfile::insertChannel(quint32 channel,
11,968✔
233
                                    QLCInputChannel* ich)
234
{
235
    if (ich != NULL && m_channels.contains(channel) == false)
11,968✔
236
    {
237
        m_channels.insert(channel, ich);
11,967✔
238
        return true;
11,967✔
239
    }
240
    else
241
    {
242
        return false;
1✔
243
    }
244
}
245

246
bool QLCInputProfile::removeChannel(quint32 channel)
6✔
247
{
248
    if (m_channels.contains(channel) == true)
6✔
249
    {
250
        QLCInputChannel* ich = m_channels.take(channel);
2✔
251
        Q_ASSERT(ich != NULL);
2✔
252
        delete ich;
2✔
253
        return true;
2✔
254
    }
255
    else
256
    {
257
        return false;
4✔
258
    }
259
}
260

261
bool QLCInputProfile::remapChannel(QLCInputChannel* ich, quint32 number)
3✔
262
{
263
    if (ich == NULL)
3✔
264
        return false;
1✔
265

266
    quint32 old = channelNumber(ich);
2✔
267
    if (old != QLCChannel::invalid() && m_channels.contains(number) == false)
2✔
268
    {
269
        m_channels.take(old);
1✔
270
        insertChannel(number, ich);
1✔
271
        return true;
1✔
272
    }
273
    else
274
    {
275
        return false;
1✔
276
    }
277
}
278

279
QLCInputChannel* QLCInputProfile::channel(quint32 channel) const
75✔
280
{
281
    if (m_channels.contains(channel) == true)
75✔
282
        return m_channels[channel];
60✔
283
    else
284
        return NULL;
15✔
285
}
286

287
quint32 QLCInputProfile::channelNumber(const QLCInputChannel* channel) const
6✔
288
{
289
    if (channel == NULL)
6✔
290
        return QLCChannel::invalid();
1✔
291

292
    QMapIterator <quint32,QLCInputChannel*> it(m_channels);
10✔
293
    while (it.hasNext() == true)
10✔
294
    {
295
        it.next();
9✔
296
        if (it.value() == channel)
9✔
297
            return it.key();
4✔
298
    }
299

300
    return QLCChannel::invalid();
1✔
301
}
302

303
QMap <quint32,QLCInputChannel*> QLCInputProfile::channels() const
29✔
304
{
305
    return m_channels;
29✔
306
}
307

308
void QLCInputProfile::destroyChannels()
56✔
309
{
310
    /* Delete existing channels but leave the pointers there */
311
    QMutableMapIterator <quint32,QLCInputChannel*> it(m_channels);
56✔
312
    while (it.hasNext() == true)
3,982✔
313
        delete it.next().value();
3,926✔
314

315
    /* Clear the list of freed pointers */
316
    m_channels.clear();
56✔
317
}
56✔
318

319
/****************************************************************************
320
 * Load & Save
321
 ****************************************************************************/
322

323
QLCInputProfile* QLCInputProfile::loader(const QString& path)
106✔
324
{
325
    QXmlStreamReader *doc = QLCFile::getXMLReader(path);
106✔
326
    if (doc == NULL || doc->device() == NULL || doc->hasError())
106✔
327
    {
328
        qWarning() << Q_FUNC_INFO << "Unable to load input profile from" << path;
2✔
329
        return NULL;
2✔
330
    }
331

332
    QLCInputProfile* profile = new QLCInputProfile();
104✔
333
    if (profile->loadXML(*doc) == false)
104✔
334
    {
335
        qWarning() << path << QString("%1\nLine %2, column %3")
×
336
                    .arg(doc->errorString())
×
337
                    .arg(doc->lineNumber())
×
338
                    .arg(doc->columnNumber());
×
339

340
        delete profile;
×
341
        profile = NULL;
×
342
    }
343
    else
344
    {
345
        profile->m_path = path;
104✔
346
    }
347

348
    QLCFile::releaseXMLReader(doc);
104✔
349

350
    return profile;
104✔
351
}
352

353
bool QLCInputProfile::loadXML(QXmlStreamReader& doc)
107✔
354
{
355
    if (doc.readNextStartElement() == false)
107✔
356
        return false;
2✔
357

358
    if (doc.name() == KXMLQLCInputProfile)
105✔
359
    {
360
        while (doc.readNextStartElement())
12,471✔
361
        {
362
            if (doc.name() == KXMLQLCCreator)
12,366✔
363
            {
364
                /* Ignore this block */
365
                doc.skipCurrentElement();
104✔
366
            }
367
            else if (doc.name() == KXMLQLCInputProfileManufacturer)
12,262✔
368
            {
369
                setManufacturer(doc.readElementText());
105✔
370
            }
371
            else if (doc.name() == KXMLQLCInputProfileModel)
12,157✔
372
            {
373
                setModel(doc.readElementText());
105✔
374
            }
375
            else if (doc.name() == KXMLQLCInputProfileType)
12,052✔
376
            {
377
                setType(stringToType(doc.readElementText()));
104✔
378
            }
379
            else if (doc.name() == KXMLQLCInputProfileMidiSendNoteOff)
11,948✔
380
            {
381
                if (doc.readElementText() == KXMLQLCFalse)
15✔
382
                    setMidiSendNoteOff(false);
15✔
383
                else
384
                    setMidiSendNoteOff(true);
×
385
            }
386
            else if (doc.name() == KXMLQLCInputChannel)
11,933✔
387
            {
388
                QString str = doc.attributes().value(KXMLQLCInputChannelNumber).toString();
35,799✔
389
                if (str.isEmpty() == false)
11,933✔
390
                {
391
                    quint32 ch = str.toInt();
11,933✔
392
                    QLCInputChannel* ich = new QLCInputChannel();
11,933✔
393
                    if (ich->loadXML(doc) == true)
11,933✔
394
                        insertChannel(ch, ich);
11,933✔
395
                    else
396
                        delete ich;
×
397
                }
398
                else
399
                    doc.skipCurrentElement();
×
400
            }
401
        }
402

403
        return true;
105✔
404
    }
405
    else
406
    {
407
        qWarning() << Q_FUNC_INFO << "Input profile not found";
×
408
        return false;
×
409
    }
410
}
411

412
bool QLCInputProfile::saveXML(const QString& fileName)
2✔
413
{
414
    QFile file(fileName);
4✔
415
    if (file.open(QIODevice::WriteOnly) == false)
2✔
416
    {
417
        qWarning() << Q_FUNC_INFO << "Unable to write to" << fileName;
1✔
418
        return false;
1✔
419
    }
420

421
    QXmlStreamWriter doc(&file);
2✔
422
    doc.setAutoFormatting(true);
1✔
423
    doc.setAutoFormattingIndent(1);
1✔
424
    QLCFile::writeXMLHeader(&doc, KXMLQLCInputProfile);
1✔
425

426
    doc.writeTextElement(KXMLQLCInputProfileManufacturer, m_manufacturer);
1✔
427
    doc.writeTextElement(KXMLQLCInputProfileModel, m_model);
1✔
428
    doc.writeTextElement(KXMLQLCInputProfileType, typeToString(m_type));
1✔
429

430
    if (midiSendNoteOff() == false)
1✔
431
        doc.writeTextElement(KXMLQLCInputProfileMidiSendNoteOff, QString(KXMLQLCFalse));
×
432

433
    /* Write channels to the document */
434
    QMapIterator <quint32, QLCInputChannel*> it(m_channels);
1✔
435
    while (it.hasNext() == true)
4✔
436
    {
437
        it.next();
3✔
438
        it.value()->saveXML(&doc, it.key());
3✔
439
    }
440

441
    m_path = fileName;
1✔
442
    /* End the document and close all the open elements */
443
    doc.writeEndDocument();
1✔
444
    file.close();
1✔
445

446
    return true;
1✔
447
}
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