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

mcallegari / qlcplus / 6633445329

24 Oct 2023 10:56PM UTC coverage: 28.07% (+0.03%) from 28.038%
6633445329

push

github

mcallegari
qmlui: fix qmake build

15376 of 54778 relevant lines covered (28.07%)

20279.08 hits per line

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

83.17
/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()
124✔
44
    : m_manufacturer(QString())
45
    , m_model(QString())
46
    , m_path(QString())
47
    , m_type(MIDI)
48
    , m_midiSendNoteOff(true)
124✔
49
{
50
}
124✔
51

52
QLCInputProfile::~QLCInputProfile()
89✔
53
{
54
    destroyChannels();
53✔
55
}
89✔
56

57
QLCInputProfile *QLCInputProfile::createCopy()
1✔
58
{
59
    QLCInputProfile *copy = new QLCInputProfile();
1✔
60
    copy->setManufacturer(this->manufacturer());
1✔
61
    copy->setModel(this->model());
1✔
62
    copy->setType(this->type());
1✔
63
    copy->setPath(this->path());
1✔
64
    copy->setMidiSendNoteOff(this->midiSendNoteOff());
1✔
65

66
    /* Copy the other profile's channels */
67
    QMapIterator <quint32,QLCInputChannel*> it(this->channels());
2✔
68
    while (it.hasNext() == true)
5✔
69
    {
70
        it.next();
4✔
71
        copy->insertChannel(it.key(), it.value()->createCopy());
4✔
72
    }
73

74
    return copy;
2✔
75
}
76

77
QLCInputProfile& QLCInputProfile::operator=(const QLCInputProfile& profile)
1✔
78
{
79
    if (this != &profile)
1✔
80
    {
81
        /* Copy basic properties */
82
        m_manufacturer = profile.m_manufacturer;
1✔
83
        m_model = profile.m_model;
1✔
84
        m_path = profile.m_path;
1✔
85
        m_type = profile.m_type;
1✔
86
        m_midiSendNoteOff = profile.m_midiSendNoteOff;
1✔
87
        m_globalSettingsMap = profile.m_globalSettingsMap;
1✔
88

89
        /* Destroy all existing channels */
90
        destroyChannels();
1✔
91

92
        /* Copy the other profile's channels */
93
        QMapIterator <quint32,QLCInputChannel*> it(profile.m_channels);
2✔
94
        while (it.hasNext() == true)
5✔
95
        {
96
            it.next();
4✔
97
            insertChannel(it.key(), it.value()->createCopy());
4✔
98
        }
99
    }
100

101
    return *this;
1✔
102
}
103

104
/****************************************************************************
105
 * profile information
106
 ****************************************************************************/
107

108
void QLCInputProfile::setManufacturer(const QString& manufacturer)
117✔
109
{
110
    m_manufacturer = manufacturer;
117✔
111
}
117✔
112

113
QString QLCInputProfile::manufacturer() const
7✔
114
{
115
    return m_manufacturer;
7✔
116
}
117

118
void QLCInputProfile::setModel(const QString& model)
113✔
119
{
120
    m_model = model;
113✔
121
}
113✔
122

123
QString QLCInputProfile::model() const
7✔
124
{
125
    return m_model;
7✔
126
}
127

128
QString QLCInputProfile::name() const
1,975✔
129
{
130
    return QString("%1 %2").arg(m_manufacturer).arg(m_model);
1,975✔
131
}
132

133
void QLCInputProfile::setPath(QString path)
1✔
134
{
135
    m_path = path;
1✔
136
}
1✔
137

138
QString QLCInputProfile::path() const
2✔
139
{
140
    return m_path;
2✔
141
}
142

143
void QLCInputProfile::setType(QLCInputProfile::Type type)
105✔
144
{
145
    m_type = type;
105✔
146
}
105✔
147

148
QLCInputProfile::Type QLCInputProfile::type() const
1✔
149
{
150
    return m_type;
1✔
151
}
152

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

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

190
QList<QLCInputProfile::Type> QLCInputProfile::types()
×
191
{
192
    QList<Type> result;
×
193
    result
194
        << MIDI
×
195
        << OS2L
×
196
        << OSC
×
197
        << HID
×
198
        << DMX
×
199
        << Enttec;
×
200
    return result;
×
201
}
202

203
/********************************************************************
204
 * Plugin-specific global settings
205
 ********************************************************************/
206

207
void QLCInputProfile::setMidiSendNoteOff(bool enable)
16✔
208
{
209
    m_midiSendNoteOff = enable;
16✔
210
    m_globalSettingsMap["MIDISendNoteOff"] = QVariant(enable);
16✔
211
}
16✔
212

213
bool QLCInputProfile::midiSendNoteOff() const
2✔
214
{
215
    return m_midiSendNoteOff;
2✔
216
}
217

218
QMap<QString, QVariant> QLCInputProfile::globalSettings() const
5✔
219
{
220
    return m_globalSettingsMap;
5✔
221
}
222

223
/****************************************************************************
224
 * Channels
225
 ****************************************************************************/
226

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

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

256
bool QLCInputProfile::remapChannel(QLCInputChannel* ich, quint32 number)
3✔
257
{
258
    if (ich == NULL)
3✔
259
        return false;
1✔
260

261
    quint32 old = channelNumber(ich);
2✔
262
    if (old != QLCChannel::invalid() && m_channels.contains(number) == false)
2✔
263
    {
264
        m_channels.take(old);
1✔
265
        insertChannel(number, ich);
1✔
266
        return true;
1✔
267
    }
268
    else
269
    {
270
        return false;
1✔
271
    }
272
}
273

274
QLCInputChannel* QLCInputProfile::channel(quint32 channel) const
75✔
275
{
276
    if (m_channels.contains(channel) == true)
75✔
277
        return m_channels[channel];
60✔
278
    else
279
        return NULL;
15✔
280
}
281

282
quint32 QLCInputProfile::channelNumber(const QLCInputChannel* channel) const
6✔
283
{
284
    if (channel == NULL)
6✔
285
        return QLCChannel::invalid();
1✔
286

287
    QMapIterator <quint32,QLCInputChannel*> it(m_channels);
10✔
288
    while (it.hasNext() == true)
10✔
289
    {
290
        it.next();
9✔
291
        if (it.value() == channel)
9✔
292
            return it.key();
4✔
293
    }
294

295
    return QLCChannel::invalid();
1✔
296
}
297

298
QMap <quint32,QLCInputChannel*> QLCInputProfile::channels() const
30✔
299
{
300
    return m_channels;
30✔
301
}
302

303
void QLCInputProfile::destroyChannels()
54✔
304
{
305
    /* Delete existing channels but leave the pointers there */
306
    QMutableMapIterator <quint32,QLCInputChannel*> it(m_channels);
54✔
307
    while (it.hasNext() == true)
3,976✔
308
        delete it.next().value();
3,922✔
309

310
    /* Clear the list of freed pointers */
311
    m_channels.clear();
54✔
312
}
54✔
313

314
/****************************************************************************
315
 * Load & Save
316
 ****************************************************************************/
317

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

327
    QLCInputProfile* profile = new QLCInputProfile();
104✔
328
    if (profile->loadXML(*doc) == false)
104✔
329
    {
330
        qWarning() << path << QString("%1\nLine %2, column %3")
×
331
                    .arg(doc->errorString())
×
332
                    .arg(doc->lineNumber())
×
333
                    .arg(doc->columnNumber());
×
334

335
        delete profile;
×
336
        profile = NULL;
×
337
    }
338
    else
339
    {
340
        profile->m_path = path;
104✔
341
    }
342

343
    QLCFile::releaseXMLReader(doc);
104✔
344

345
    return profile;
104✔
346
}
347

348
bool QLCInputProfile::loadXML(QXmlStreamReader& doc)
107✔
349
{
350
    if (doc.readNextStartElement() == false)
107✔
351
        return false;
2✔
352

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

398
        return true;
105✔
399
    }
400
    else
401
    {
402
        qWarning() << Q_FUNC_INFO << "Input profile not found";
×
403
        return false;
×
404
    }
405
}
406

407
bool QLCInputProfile::saveXML(const QString& fileName)
2✔
408
{
409
    QFile file(fileName);
4✔
410
    if (file.open(QIODevice::WriteOnly) == false)
2✔
411
    {
412
        qWarning() << Q_FUNC_INFO << "Unable to write to" << fileName;
1✔
413
        return false;
1✔
414
    }
415

416
    QXmlStreamWriter doc(&file);
2✔
417
    doc.setAutoFormatting(true);
1✔
418
    doc.setAutoFormattingIndent(1);
1✔
419
    QLCFile::writeXMLHeader(&doc, KXMLQLCInputProfile);
1✔
420

421
    doc.writeTextElement(KXMLQLCInputProfileManufacturer, m_manufacturer);
1✔
422
    doc.writeTextElement(KXMLQLCInputProfileModel, m_model);
1✔
423
    doc.writeTextElement(KXMLQLCInputProfileType, typeToString(m_type));
1✔
424

425
    if (midiSendNoteOff() == false)
1✔
426
        doc.writeTextElement(KXMLQLCInputProfileMidiSendNoteOff, QString(KXMLQLCFalse));
×
427

428
    /* Write channels to the document */
429
    QMapIterator <quint32, QLCInputChannel*> it(m_channels);
1✔
430
    while (it.hasNext() == true)
4✔
431
    {
432
        it.next();
3✔
433
        it.value()->saveXML(&doc, it.key());
3✔
434
    }
435

436
    m_path = fileName;
1✔
437
    /* End the document and close all the open elements */
438
    doc.writeEndDocument();
1✔
439
    file.close();
1✔
440

441
    return true;
1✔
442
}
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