• 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

0.0
/ui/src/dmxdumpfactory.cpp
1
/*
2
  Q Light Controller Plus
3
  dmxdumpfactory.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 <QTreeWidgetItem>
21
#include <QTreeWidget>
22
#include <QDebug>
23
#include <QSettings>
24

25
#include "dmxdumpfactoryproperties.h"
26
#include "fixturetreewidget.h"
27
#include "functionselection.h"
28
#include "virtualconsole.h"
29
#include "dmxdumpfactory.h"
30
#include "universe.h"
31
#include "function.h"
32
#include "vcwidget.h"
33
#include "vcbutton.h"
34
#include "vcslider.h"
35
#include "chaser.h"
36
#include "scene.h"
37
#include "doc.h"
38

39
#define KColumnName  0
40
#define KColumnType  1
41
#define KColumnID    2
42

43
#define KColumnTargetName 0
44
#define KColumnTargetID   1
45

46
#define SETTINGS_GEOMETRY "dmxdumpfactory/geometry"
47

48
DmxDumpFactory::DmxDumpFactory(Doc *doc, DmxDumpFactoryProperties *props, QWidget *parent)
×
49
    : QDialog(parent)
50
    , m_doc(doc)
×
51
    , m_properties(props)
×
52
    , m_selectedSceneID(Function::invalidId())
×
53
{
54
    Q_ASSERT(doc != NULL);
55

56
    setupUi(this);
×
57

58
    quint32 treeFlags = FixtureTreeWidget::ChannelType |
59
                        FixtureTreeWidget::ChannelSelection;
60

61
    m_fixturesTree = new FixtureTreeWidget(m_doc, treeFlags, this);
×
62
    m_fixturesTree->setIconSize(QSize(24, 24));
×
63
    m_fixturesTree->setSortingEnabled(false);
×
64

65
    m_treeLayout->addWidget(m_fixturesTree);
×
66
    m_fixturesTree->setChannelsMask(m_properties->channelsMask());
×
67

68
    m_fixturesTree->updateTree();
×
69

70
    if (m_properties->selectedTarget() == DmxDumpFactoryProperties::VCButton)
×
71
        m_buttonRadio->setChecked(true);
×
72
    else if (m_properties->selectedTarget() == DmxDumpFactoryProperties::VCSlider)
×
73
        m_sliderRadio->setChecked(true);
×
74
    else
75
        slotUpdateChasersTree();
×
76

77
    m_dumpAllRadio->setText(tr("Dump all channels (%1 Universes, %2 Fixtures, %3 Channels)")
×
78
                            .arg(m_fixturesTree->universeCount()).arg(m_fixturesTree->fixturesCount()).arg(m_fixturesTree->channelsCount()));
×
79

80
    m_sceneName->setText(tr("New Scene From Live %1").arg(m_doc->nextFunctionID()));
×
81
    if (m_properties->dumpChannelsMode() == true)
×
82
        m_dumpAllRadio->setChecked(true);
×
83
    else
84
        m_dumpSelectedRadio->setChecked(true);
×
85

86
    if (m_properties->nonZeroValuesMode() == true)
×
87
        m_nonZeroCheck->setChecked(true);
×
88

89
    QSettings settings;
×
90
    QVariant geometrySettings = settings.value(SETTINGS_GEOMETRY);
×
91
    if (geometrySettings.isValid() == true)
×
92
        restoreGeometry(geometrySettings.toByteArray());
×
93

94
    connect(m_sceneButton, SIGNAL(clicked(bool)),
×
95
            this, SLOT(slotSelectSceneButtonClicked()));
96
}
×
97

98
DmxDumpFactory::~DmxDumpFactory()
×
99
{
100
    QSettings settings;
×
101
    settings.setValue(SETTINGS_GEOMETRY, saveGeometry());
×
102
}
×
103

104
void DmxDumpFactory::slotUpdateChasersTree()
×
105
{
106
    m_addtoTree->clear();
×
107
    foreach (Function *f, m_doc->functionsByType(Function::ChaserType))
×
108
    {
109
        Chaser *chaser = qobject_cast<Chaser*>(f);
110
        QTreeWidgetItem *item = new QTreeWidgetItem(m_addtoTree);
×
111
        item->setText(KColumnTargetName, chaser->name());
×
112
        item->setText(KColumnTargetID, QString::number(chaser->id()));
×
113
        item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
×
114
        if (m_properties->isChaserSelected(chaser->id()))
×
115
            item->setCheckState(KColumnName, Qt::Checked);
×
116
        else
117
            item->setCheckState(KColumnName, Qt::Unchecked);
×
118
    }
119
}
×
120

121
void DmxDumpFactory::slotUpdateButtons()
×
122
{
123
    updateWidgetsTree(VCWidget::ButtonWidget);
×
124
}
×
125

126
void DmxDumpFactory::slotUpdateSliders()
×
127
{
128
    updateWidgetsTree(VCWidget::SliderWidget);
×
129
}
×
130

131
void DmxDumpFactory::slotSelectSceneButtonClicked()
×
132
{
133
    FunctionSelection fs(this, m_doc);
×
134
    fs.setMultiSelection(false);
×
135
    fs.setFilter(Function::SceneType, true);
×
136

137
    if (fs.exec() == QDialog::Accepted && fs.selection().size() > 0)
×
138
    {
139
        m_selectedSceneID = fs.selection().first();
×
140
        Scene *scene = qobject_cast<Scene*>(m_doc->function(m_selectedSceneID));
×
141
        if (scene == NULL)
×
142
            return;
×
143

144
        m_sceneName->setText(scene->name());
×
145
        m_dumpSelectedRadio->setChecked(true);
×
146
        QByteArray chMask = m_properties->channelsMask();
×
147
        chMask.fill(0);
×
148

149
        foreach (SceneValue scv, scene->values())
×
150
        {
151
            Fixture *fxi = m_doc->fixture(scv.fxi);
×
152
            if (fxi == NULL)
×
153
                continue;
154
            quint32 absAddress = fxi->universeAddress() + scv.channel;
×
155
            if (chMask.length() > (int)absAddress)
×
156
                chMask[absAddress] = 1;
×
157
        }
×
158
        m_properties->setChannelsMask(chMask);
×
159
        m_fixturesTree->setChannelsMask(chMask);
×
160
        m_fixturesTree->updateTree();
×
161
    }
×
162
}
×
163

164
QList<VCWidget *> DmxDumpFactory::getChildren(VCWidget *obj, int type)
×
165
{
166
    QList<VCWidget *> list;
167
    if (obj == NULL)
×
168
        return list;
169
    QListIterator <VCWidget*> it(obj->findChildren<VCWidget*>());
×
170
    while (it.hasNext() == true)
×
171
    {
172
        VCWidget* child = it.next();
×
173
        qDebug() << Q_FUNC_INFO << "append: " << child->caption();
174
        if (type == child->type())
×
175
            list.append(child);
×
176
    }
177
    return list;
178
}
×
179

180
void DmxDumpFactory::updateWidgetsTree(int type)
×
181
{
182
    m_addtoTree->clear();
×
183
    VCFrame *contents = VirtualConsole::instance()->contents();
×
184
    QList<VCWidget *> widgetsList = getChildren((VCWidget *)contents, type);
×
185

186
    foreach (QObject *object, widgetsList)
×
187
    {
188
        VCWidget *widget = qobject_cast<VCWidget *>(object);
189

190
        QTreeWidgetItem *item = new QTreeWidgetItem(m_addtoTree);
×
191
        item->setText(KColumnTargetName, widget->caption());
×
192
        item->setIcon(KColumnTargetName, VCWidget::typeToIcon(widget->type()));
×
193
        item->setText(KColumnTargetID, QString::number(widget->id()));
×
194
        item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
×
195
        item->setCheckState(KColumnName, Qt::Unchecked);
×
196
    }
197
}
×
198

199
void DmxDumpFactory::slotDumpModeChanged(bool mode)
×
200
{
201
    if (mode == true)
×
202
        m_fixturesTree->setEnabled(false);
×
203
    else
204
        m_fixturesTree->setEnabled(true);
×
205
    m_properties->setDumpChannelsMode(mode);
×
206
}
×
207

208
void DmxDumpFactory::slotDumpNonZeroChanged(bool active)
×
209
{
210
    m_properties->setNonZeroValuesMode(active);
×
211
}
×
212

213
void DmxDumpFactory::accept()
×
214
{
215
    QByteArray dumpMask = m_properties->channelsMask();
×
216
    QList<Universe*> ua = m_doc->inputOutputMap()->claimUniverses();
×
217

218
    QByteArray preGMValues(ua.size() * UNIVERSE_SIZE, 0); //= ua->preGMValues();
×
219

220
    for (int i = 0; i < ua.count(); ++i)
×
221
    {
222
        const int offset = i * UNIVERSE_SIZE;
×
223
        preGMValues.replace(offset, UNIVERSE_SIZE, ua.at(i)->preGMValues());
×
224
        if (ua.at(i)->passthrough())
×
225
        {
226
            for (int j = 0; j < UNIVERSE_SIZE; ++j)
×
227
            {
228
                const int ofs = offset + j;
×
229
                preGMValues[ofs] =
×
230
                    static_cast<char>(ua.at(i)->applyPassthrough(j, static_cast<uchar>(preGMValues[ofs])));
×
231
            }
232
        }
233
    }
234

235
    m_doc->inputOutputMap()->releaseUniverses(false);
×
236

237
    Scene *newScene = NULL;
238
    if (m_selectedSceneID != Function::invalidId())
×
239
        newScene = qobject_cast<Scene*>(m_doc->function(m_selectedSceneID));
×
240

241
    for (int t = 0; t < m_fixturesTree->topLevelItemCount(); t++)
×
242
    {
243
        QTreeWidgetItem *uniItem = m_fixturesTree->topLevelItem(t);
×
244
        if (newScene == NULL && (m_dumpAllRadio->isChecked() ||
×
245
             uniItem->checkState(KColumnName) != Qt::Unchecked))
×
246
                newScene = new Scene(m_doc);
×
247
        //int uni = uniItem->text(KColumnID).toInt();
248
        for (int f = 0; f < uniItem->childCount(); f++)
×
249
        {
250
            QTreeWidgetItem *fixItem = uniItem->child(f);
×
251
            quint32 fxID = fixItem->data(KColumnName, PROP_ID).toUInt();
×
252
            Fixture *fxi = m_doc->fixture(fxID);
×
253
            if (fxi != NULL)
×
254
            {
255
                quint32 baseAddress = fxi->universeAddress();
×
256
                for (int c = 0; c < fixItem->childCount(); c++)
×
257
                {
258
                    QTreeWidgetItem *chanItem = fixItem->child(c);
×
259
                    quint32 channel = chanItem->data(KColumnName, PROP_CHANNEL).toUInt();
×
260

261
                    if (m_dumpAllRadio->isChecked())
×
262
                    {
263
                        dumpMask[baseAddress + channel] = 1;
×
264
                        uchar value = preGMValues.at(baseAddress + channel);
×
265
                        if (m_nonZeroCheck->isChecked() == false ||
×
266
                           (m_nonZeroCheck->isChecked() == true && value > 0))
×
267
                        {
268
                            SceneValue sv = SceneValue(fxID, channel, value);
×
269
                            newScene->setValue(sv);
×
270
                        }
×
271
                    }
272
                    else
273
                    {
274
                        //qDebug() << "Fix: " << fxID << "chan:" << channel << "addr:" << (baseAddress + channel);
275
                        if (chanItem->checkState(KColumnName) == Qt::Checked)
×
276
                        {
277
                            dumpMask[baseAddress + channel] = 1;
×
278
                            uchar value = preGMValues.at(baseAddress + channel);
×
279
                            if (m_nonZeroCheck->isChecked() == false ||
×
280
                               (m_nonZeroCheck->isChecked() == true && value > 0))
×
281
                            {
282
                                SceneValue sv = SceneValue(fxID, channel, value);
×
283
                                newScene->setValue(sv);
×
284
                            }
×
285
                        }
286
                        else
287
                            dumpMask[baseAddress + channel] = 0;
×
288
                    }
289
                }
290
            }
291
        }
292
    }
293
    /** If the Scene is valid, add it to QLC+ functions */
294
    if (newScene != NULL)
×
295
    {
296
        bool addedToDoc = false;
297

298
        if (m_selectedSceneID != Function::invalidId() &&
×
299
            m_doc->function(m_selectedSceneID) != NULL)
×
300
        {
301
            addedToDoc = true;
302
        }
303
        else
304
        {
305
            newScene->setName(m_sceneName->text());
×
306
            addedToDoc = m_doc->addFunction(newScene);
×
307
        }
308
        if (addedToDoc == true)
×
309
        {
310
            quint32 sceneID = newScene->id();
×
311
            /** Now add the Scene to the selected Chasers */
312
            for (int tc = 0; tc < m_addtoTree->topLevelItemCount(); tc++)
×
313
            {
314
                QTreeWidgetItem *targetItem = m_addtoTree->topLevelItem(tc);
×
315
                quint32 targetID = targetItem->text(KColumnTargetID).toUInt();
×
316
                if (targetItem->checkState(KColumnTargetName) == Qt::Checked)
×
317
                {
318
                    if (m_chaserRadio->isChecked())
×
319
                    {
320
                        Chaser *chaser = qobject_cast<Chaser*>(m_doc->function(targetID));
×
321
                        if (chaser != NULL)
×
322
                        {
323
                            ChaserStep chsStep(sceneID);
×
324
                            chaser->addStep(chsStep);
×
325
                            m_properties->addChaserID(targetID);
×
326
                        }
327
                    }
328
                    else if (m_buttonRadio->isChecked())
×
329
                    {
330
                        VCButton *button = qobject_cast<VCButton*>(VirtualConsole::instance()->widget(targetID));
×
331
                        if (button != NULL)
×
332
                        {
333
                            button->setFunction(newScene->id());
×
334
                            button->setCaption(newScene->name());
×
335
                        }
336
                    }
337
                    else if (m_sliderRadio->isChecked())
×
338
                    {
339
                        VCSlider *slider = qobject_cast<VCSlider*>(VirtualConsole::instance()->widget(targetID));
×
340
                        if (slider != NULL)
×
341
                        {
342
                            slider->setPlaybackFunction(newScene->id());
×
343
                            slider->setCaption(newScene->name());
×
344
                        }
345
                    }
346
                }
347
                else
348
                    m_properties->removeChaserID(targetID);
×
349
            }
350
        }
351
    }
352

353
    m_properties->setChannelsMask(dumpMask);
×
354
    if (m_chaserRadio->isChecked())
×
355
        m_properties->setSelectedTarget(DmxDumpFactoryProperties::Chaser);
×
356
    else if (m_buttonRadio->isChecked())
×
357
        m_properties->setSelectedTarget(DmxDumpFactoryProperties::VCButton);
×
358
    else if (m_sliderRadio->isChecked())
×
359
        m_properties->setSelectedTarget(DmxDumpFactoryProperties::VCSlider);
×
360

361
    /* Close dialog */
362
    QDialog::accept();
×
363
}
×
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