• 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

88.22
/ui/src/addfixture.cpp
1
/*
2
  Q Light Controller
3
  addfixture.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 <QDialogButtonBox>
21
#include <QTreeWidgetItem>
22
#include <QTreeWidget>
23
#include <QPushButton>
24
#include <QMessageBox>
25
#include <QHeaderView>
26
#include <QByteArray>
27
#include <QSettings>
28
#include <QLineEdit>
29
#include <QComboBox>
30
#include <QSpinBox>
31
#include <QLabel>
32
#include <QDebug>
33
#include <QAction>
34

35
#include "qlcfixturedefcache.h"
36
#include "qlcfixturemode.h"
37
#include "qlcfixturedef.h"
38

39
#include "addresstool.h"
40
#include "addfixture.h"
41
#include "apputil.h"
42
#include "doc.h"
43

44
#define SETTINGS_GEOMETRY "addfixture/geometry"
45

46
#define KColumnName 0
47

48
AddFixture::AddFixture(QWidget* parent, const Doc* doc, const Fixture* fxi)
7✔
49
    : QDialog(parent)
50
    , m_doc(doc)
7✔
51
{
52
    m_addressValue = 0;
7✔
53
    m_universeValue = 0;
7✔
54
    m_amountValue = 1;
7✔
55
    m_gapValue = 0;
7✔
56
    m_channelsValue = 1;
7✔
57
    m_fixtureDef = NULL;
7✔
58
    m_mode = NULL;
7✔
59
    m_fxiCount = 0;
7✔
60
    m_fixtureID = Fixture::invalidId();
7✔
61
    m_invalidAddressFlag = false;
7✔
62

63
    setupUi(this);
7✔
64
    m_addrErrorLabel->hide();
7✔
65

66
    QAction* action = new QAction(this);
7✔
67
    action->setShortcut(QKeySequence(QKeySequence::Close));
7✔
68
    connect(action, SIGNAL(triggered(bool)), this, SLOT(reject()));
7✔
69
    addAction(action);
7✔
70

71
    connect(m_tree, SIGNAL(itemSelectionChanged()),
7✔
72
            this, SLOT(slotSelectionChanged()));
73
    connect(m_tree, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)),
7✔
74
            this, SLOT(slotTreeDoubleClicked(QTreeWidgetItem*)));
75
    connect(m_modeCombo, SIGNAL(activated(int)),
7✔
76
            this, SLOT(slotModeActivated(int)));
77
    connect(m_universeCombo, SIGNAL(activated(int)),
7✔
78
            this, SLOT(slotUniverseActivated(int)));
79
    connect(m_addressSpin, SIGNAL(valueChanged(int)),
7✔
80
            this, SLOT(slotAddressChanged(int)));
81
    connect(m_channelsSpin, SIGNAL(valueChanged(int)),
7✔
82
            this, SLOT(slotChannelsChanged(int)));
83
    connect(m_nameEdit, SIGNAL(textEdited(const QString&)),
7✔
84
            this, SLOT(slotNameEdited(const QString&)));
85
    connect(m_gapSpin, SIGNAL(valueChanged(int)),
7✔
86
            this, SLOT(slotGapSpinChanged(int)));
87
    connect(m_amountSpin, SIGNAL(valueChanged(int)),
7✔
88
            this, SLOT(slotAmountSpinChanged(int)));
89
    connect(m_searchEdit, SIGNAL(textChanged(QString)),
7✔
90
            this, SLOT(slotSearchFilterChanged(QString)));
91
    connect(m_diptoolButton, SIGNAL(clicked()),
7✔
92
            this, SLOT(slotDiptoolButtonClicked()));
93

94
    /* Fill fixture definition tree (and select a fixture def) */
95
    if (fxi != NULL)
7✔
96
    {
97
        fillTree(fxi->fixtureDef()->manufacturer(), fxi->fixtureDef()->model());
2✔
98
        m_fixtureID = fxi->id();
2✔
99
    }
100
    else
101
        fillTree(KXMLFixtureGeneric, KXMLFixtureGeneric);
5✔
102

103
    m_fixturesCount->setText(tr("Fixtures found: %1").arg(m_fxiCount));
7✔
104

105
    /* Fill universe combo with available universes */
106
    m_universeCombo->addItems(m_doc->inputOutputMap()->universeNames());
7✔
107

108
    /* Simulate first selection and find the next free address */
109
    slotSelectionChanged();
7✔
110

111
    if (fxi != NULL)
7✔
112
    {
113
        // Universe
114
        m_universeCombo->setCurrentIndex(fxi->universe());
2✔
115
        slotUniverseActivated(fxi->universe());
2✔
116

117
        m_addressSpin->setValue(fxi->address() + 1);
2✔
118
        m_addressValue = fxi->address();
2✔
119

120
        m_multipleGroup->setEnabled(false);
2✔
121

122
        // Name
123
        m_nameEdit->setText(fxi->name());
2✔
124
        slotNameEdited(fxi->name());
2✔
125
        m_nameEdit->setModified(true); // Prevent auto-naming
2✔
126

127
        // Mode
128
        int index = m_modeCombo->findText(fxi->fixtureMode()->name());
2✔
129
        if (index != -1)
2✔
130
        {
131
            m_channelsSpin->setValue(fxi->channels());
2✔
132
            m_modeCombo->setCurrentIndex(index);
2✔
133
            slotModeActivated(index);
2✔
134
        }
135
    }
136
    else
137
    {
138
        slotUniverseActivated(0);
5✔
139
        findAddress();
5✔
140

141
        m_channelsSpin->setValue(1);
5✔
142
    }
143

144
    QSettings settings;
7✔
145
    QVariant var = settings.value(SETTINGS_GEOMETRY);
14✔
146
    if (var.isValid() == true)
7✔
147
        restoreGeometry(var.toByteArray());
6✔
148
    AppUtil::ensureWidgetIsVisible(this);
7✔
149

150
    // Set focus on the search bar
151
    m_searchEdit->setFocus();
7✔
152
}
7✔
153

154
AddFixture::~AddFixture()
7✔
155
{
156
    QSettings settings;
7✔
157
    settings.setValue(SETTINGS_GEOMETRY, saveGeometry());
7✔
158

159
    QList<QVariant> expanded;
160
    QTreeWidgetItem * root = m_tree->invisibleRootItem();
161

162
    for (int i=0; i < root->childCount(); i++)
987✔
163
    {
164
        QTreeWidgetItem * manuf = root->child(i);
980✔
165
        if (manuf->isExpanded())
980✔
166
        {
167
            expanded << manuf->text(KColumnName);
26✔
168
        }
169
    }
170

171
    settings.setValue(SETTINGS_EXPANDED, expanded);
7✔
172
}
7✔
173

174
/*****************************************************************************
175
 * Value getters
176
 *****************************************************************************/
177

178
QLCFixtureDef* AddFixture::fixtureDef() const
5✔
179
{
180
    return m_fixtureDef;
5✔
181
}
182

183
QLCFixtureMode *AddFixture::mode() const
5✔
184
{
185
    return m_mode;
5✔
186
}
187

188
QString AddFixture::name() const
5✔
189
{
190
    return m_nameValue;
5✔
191
}
192

193
quint32 AddFixture::address() const
5✔
194
{
195
    return m_addressValue;
5✔
196
}
197

198
quint32 AddFixture::universe() const
5✔
199
{
200
    return m_universeValue;
5✔
201
}
202

203
int AddFixture::amount() const
5✔
204
{
205
    return m_amountValue;
5✔
206
}
207

208
quint32 AddFixture::gap() const
5✔
209
{
210
    return m_gapValue;
5✔
211
}
212

213
quint32 AddFixture::channels() const
5✔
214
{
215
    return m_channelsValue;
5✔
216
}
217

218
bool AddFixture::invalidAddress()
×
219
{
220
    return m_invalidAddressFlag;
×
221
}
222

223
/*****************************************************************************
224
 * Fillers
225
 *****************************************************************************/
226

227
void AddFixture::fillTree(const QString& selectManufacturer,
7✔
228
                          const QString& selectModel)
229
{
230
    QTreeWidgetItem* parent = NULL;
231
    QTreeWidgetItem* child;
232
    QString manuf;
233
    QString model;
234
    QList<QVariant> expanded;
235

236
    QSettings settings;
7✔
237
    QVariant var = settings.value(SETTINGS_EXPANDED);
14✔
238
    if (var.isValid() == true)
7✔
239
    {
240
        expanded = var.toList();
12✔
241
    }
242

243
    /* Clear the tree of any previous data */
244
    m_tree->clear();
7✔
245

246
    QString filter = m_searchEdit->text().toLower();
7✔
247

248
    /* Add all known fixture definitions to the tree */
249
    QStringListIterator it(m_doc->fixtureDefCache()->manufacturers());
7✔
250
    while (it.hasNext() == true)
987✔
251
    {
252
        bool manufAdded = false;
253

254
        manuf = it.next();
980✔
255
        if (manuf == KXMLFixtureGeneric)
980✔
256
            continue;
7✔
257

258
        QStringListIterator modit(m_doc->fixtureDefCache()->models(manuf));
973✔
259
        while (modit.hasNext() == true)
12,229✔
260
        {
261
            model = modit.next();
11,256✔
262

263
            if (filter.isEmpty() == false &&
×
264
                manuf.toLower().contains(filter) == false &&
22,512✔
265
                model.toLower().contains(filter) == false)
11,256✔
266
                    continue;
×
267

268
            if (manufAdded == false)
11,256✔
269
            {
270
                parent = new QTreeWidgetItem(m_tree);
973✔
271
                parent->setText(KColumnName, manuf);
973✔
272
                manufAdded = true;
273
            }
274
            child = new QTreeWidgetItem(parent);
11,256✔
275
            child->setText(KColumnName, model);
11,256✔
276

277
            if (manuf == selectManufacturer &&
11,326✔
278
                    model == selectModel)
70✔
279
            {
280
                parent->setExpanded(true);
1✔
281
                m_tree->setCurrentItem(child);
1✔
282
            }
283
            else if (expanded.indexOf(manuf) != -1)
22,510✔
284
            {
285
                parent->setExpanded(true);
285✔
286
            }
287
            m_fxiCount++;
11,256✔
288
        }
289
    }
290

291
    /* Sort the tree A-Z BEFORE appending a generic entries */
292
    m_tree->sortItems(0, Qt::AscendingOrder);
7✔
293

294
    /* Create a parent for the generic devices */
295
    parent = new QTreeWidgetItem(m_tree);
7✔
296
    parent->setText(KColumnName, KXMLFixtureGeneric);
7✔
297
    QStringListIterator modit(m_doc->fixtureDefCache()->models(KXMLFixtureGeneric));
14✔
298
    while (modit.hasNext() == true)
28✔
299
    {
300
        model = modit.next();
21✔
301
        child = new QTreeWidgetItem(parent);
21✔
302
        child->setText(KColumnName, model);
21✔
303

304
        if (selectManufacturer == KXMLFixtureGeneric &&
57✔
305
                model == selectModel)
18✔
306
        {
307
            parent->setExpanded(true);
×
308
            m_tree->setCurrentItem(child);
×
309
        }
310
        else if (expanded.indexOf(manuf) != -1)
42✔
311
        {
312
            parent->setExpanded(true);
×
313
        }
314
        m_fxiCount++;
21✔
315
    }
316

317
    /* Create a child for generic dimmer device */
318
    child = new QTreeWidgetItem(parent);
7✔
319
    child->setText(KColumnName, KXMLFixtureGeneric);
7✔
320

321
    parent->sortChildren(0, Qt::AscendingOrder);
322

323
    /* Select generic dimmer by default */
324
    if (selectManufacturer == KXMLFixtureGeneric &&
20✔
325
            selectModel == KXMLFixtureGeneric)
13✔
326
    {
327
        parent->setExpanded(true);
6✔
328
        m_tree->setCurrentItem(child);
6✔
329
    }
330
}
7✔
331

332
void AddFixture::fillModeCombo(const QString& text)
17✔
333
{
334
    m_modeCombo->clear();
17✔
335

336
    if (m_fixtureDef == NULL)
17✔
337
    {
338
        m_modeCombo->setEnabled(false);
14✔
339
        m_modeCombo->addItem(text);
14✔
340
        m_modeCombo->setCurrentIndex(0);
14✔
341
        m_mode = NULL;
14✔
342
    }
343
    else
344
    {
345
        m_modeCombo->setEnabled(true);
3✔
346

347
        QListIterator <QLCFixtureMode*> it(m_fixtureDef->modes());
3✔
348
        while (it.hasNext() == true)
12✔
349
            m_modeCombo->addItem(it.next()->name());
9✔
350

351
        /* Select the first mode by default */
352
        m_modeCombo->setCurrentIndex(0);
3✔
353
        slotModeActivated(0);
3✔
354
    }
355
}
17✔
356

357
void AddFixture::findAddress()
5✔
358
{
359
    /* Find the next free address space for x fixtures, each taking y
360
       channels, leaving z channels gap in-between. */
361
    quint32 address = findAddress((m_channelsValue + m_gapValue) * m_amountValue,
10✔
362
                                  m_doc->fixtures(),
5✔
363
                                  m_doc->inputOutputMap()->universesCount());
5✔
364

365
    /* Set the address only if the channel space was really found */
366
    if (address != QLCChannel::invalid())
5✔
367
    {
368
        m_universeCombo->setCurrentIndex(address >> 9);
5✔
369
        m_addressSpin->setValue((address & 0x01FF) + 1);
5✔
370
    }
371
}
5✔
372

373
quint32 AddFixture::findAddress(quint32 numChannels,
21✔
374
                                QList<Fixture*> const& fixtures,
375
                                quint32 maxUniverses)
376
{
377
    /* Try to find contiguous space from one universe at a time */
378
    for (quint32 universe = 0; universe < maxUniverses; universe++)
30✔
379
    {
380
        quint32 ch = findAddress(universe, numChannels, fixtures);
28✔
381
        if (ch != QLCChannel::invalid())
28✔
382
            return ch;
19✔
383
    }
384

385
    return QLCChannel::invalid();
2✔
386
}
387

388
quint32 AddFixture::findAddress(quint32 universe, quint32 numChannels,
52✔
389
                                QList<Fixture*> const& fixtures, quint32 currentFixture)
390
{
391
    quint32 freeSpace = 0;
392
    quint32 maxChannels = 512;
393

394
    /* Construct a map of unallocated channels */
395
    int map[maxChannels];
52✔
396
    std::fill(map, map + maxChannels, 0);
52✔
397

398
    QListIterator <Fixture*> fxit(fixtures);
52✔
399
    while (fxit.hasNext() == true)
131✔
400
    {
401
        Fixture* fxi(fxit.next());
79✔
402
        Q_ASSERT(fxi != NULL);
403

404
        if (fxi->universe() != universe)
79✔
405
            continue;
44✔
406

407
        if (fxi->id() == currentFixture && currentFixture != Fixture::invalidId())
35✔
408
            continue;
3✔
409

410
        for (quint32 ch = 0; ch < fxi->channels(); ch++)
442✔
411
        {
412
            quint32 addr = (fxi->universeAddress() & 0x01FF) + ch;
410✔
413
            if (addr > 511)
410✔
414
                continue;
×
415

416
            map[addr] = 1;
410✔
417
        }
418
    }
419

420
    /* Try to find the next contiguous free address space */
421
    for (quint32 addr = 0; addr < maxChannels; addr++)
6,082✔
422
    {
423
        if (map[addr] == 0)
6,073✔
424
            freeSpace++;
5,798✔
425
        else
426
            freeSpace = 0;
427

428
        if (freeSpace == numChannels)
6,073✔
429
            return (addr - freeSpace + 1) | (universe << 9);
43✔
430
    }
431

432
    return QLCChannel::invalid();
9✔
433
}
52✔
434

435
void AddFixture::updateMaximumAmount()
28✔
436
{
437
    m_amountSpin->setRange(1, (513 - m_addressSpin->value()) /
28✔
438
                           (m_channelsSpin->value() + m_gapSpin->value()));
28✔
439
}
28✔
440

441
bool AddFixture::checkAddressAvailability(int value, int channels)
13✔
442
{
443
    qDebug() << "Check availability for address: " << value;
444
    for (int i = 0; i < channels; i++)
60✔
445
    {
446
        quint32 fid = m_doc->fixtureForAddress(value + i);
47✔
447
        if (fid != Fixture::invalidId() && fid != m_fixtureID)
47✔
448
            return false;
449
    }
450
    return true;
451
}
452

453
/*****************************************************************************
454
 * Slots
455
 *****************************************************************************/
456

457
void AddFixture::slotModeActivated(int modeIndex)
5✔
458
{
459
    if (m_fixtureDef == NULL)
5✔
460
        return;
461

462
    m_mode = m_fixtureDef->modes().at(modeIndex);
5✔
463
    if (m_mode == NULL)
5✔
464
    {
465
        /* Generic dimmers don't have modes, so bail out */
466
        // slotSelectionChanged();
467
        return;
468
    }
469

470
    m_channelsSpin->setValue(m_mode->channels().size());
5✔
471

472
    /* Show all selected mode channels in the list */
473
    m_channelList->clear();
5✔
474
    for (int i = 0; i < m_mode->channels().size(); i++)
44✔
475
    {
476
        QLCChannel* channel = m_mode->channel(i);
39✔
477
        Q_ASSERT(channel != NULL);
478

479
        new QListWidgetItem(
480
            QString("%1: %2").arg(i + 1).arg(channel->name()),
78✔
481
            m_channelList);
39✔
482
    }
483
}
484

485
void AddFixture::slotUniverseActivated(int universe)
7✔
486
{
487
    m_universeValue = universe;
7✔
488

489
    /* Adjust the available address range */
490
    slotChannelsChanged(m_channelsValue);
7✔
491

492
    quint32 addr = findAddress(universe, m_channelsSpin->value(), m_doc->fixtures(), m_fixtureID);
7✔
493
    if (addr != QLCChannel::invalid())
7✔
494
        m_addressSpin->setValue((addr & 0x01FF) + 1);
7✔
495
    else
496
        m_addressSpin->setValue(1);
×
497
}
7✔
498

499
void AddFixture::slotAddressChanged(int value)
2✔
500
{
501
    m_addressValue = value - 1;
2✔
502

503
    /* Set the maximum number of fixtures */
504
    updateMaximumAmount();
2✔
505

506
    checkOverlapping();
2✔
507
}
2✔
508

509
void AddFixture::slotChannelsChanged(int value)
11✔
510
{
511
    m_channelsValue = value;
11✔
512

513
    /* Set the maximum possible address so that channels cannot overflow
514
       beyond DMX's range of 512 channels */
515
    m_addressSpin->setRange(1, 513 - value);
11✔
516

517
    /* Set the maximum number of fixtures */
518
    updateMaximumAmount();
11✔
519

520
    checkOverlapping();
11✔
521
}
11✔
522

523
void AddFixture::slotNameEdited(const QString &text)
19✔
524
{
525
    /* If the user clears the text in the name field,
526
       start substituting the name with the model again. */
527
    if (text.length() == 0)
19✔
528
        m_nameEdit->setModified(false);
2✔
529
    else
530
        m_nameEdit->setModified(true);
17✔
531
    m_nameValue = text;
19✔
532
}
19✔
533

534
void AddFixture::slotAmountSpinChanged(int value)
×
535
{
536
    m_amountValue = value;
×
537

538
    checkOverlapping();
×
539
}
×
540

541
void AddFixture::slotGapSpinChanged(int value)
×
542
{
543
    m_gapValue = value;
×
544

545
    /* Set the maximum number of fixtures */
546
    updateMaximumAmount();
×
547

548
    checkOverlapping();
×
549
}
×
550

551
void AddFixture::slotSearchFilterChanged(QString)
×
552
{
553
    m_tree->blockSignals(true);
×
554
    fillTree("", "");
×
555
    m_tree->blockSignals(false);
×
556
}
×
557

558
void AddFixture::slotSelectionChanged()
17✔
559
{
560
    /* If there is no valid selection (user has selected only a
561
       manufacturer or nothing at all) don't let him press OK. */
562
    QTreeWidgetItem* item = m_tree->currentItem();
17✔
563
    if (item == NULL || item->parent() == NULL)
17✔
564
    {
565
        /* Reset the selected fixture pointer */
566
        m_fixtureDef = NULL;
2✔
567

568
        /* Since there is no m_fixtureDef, mode combo is cleared */
569
        fillModeCombo();
2✔
570

571
        /* Clear the name box unless it has been modified by user */
572
        if (m_nameEdit->isModified() == false)
2✔
573
        {
574
            m_nameEdit->setText(QString());
2✔
575
            slotNameEdited(QString());
2✔
576
            m_nameEdit->setModified(false);
2✔
577
        }
578
        m_nameEdit->setEnabled(false);
2✔
579

580
        m_channelsSpin->setValue(0);
2✔
581
        m_channelList->clear();
2✔
582
        m_addressSpin->setEnabled(false);
2✔
583
        m_universeCombo->setEnabled(false);
2✔
584

585
        m_multipleGroup->setEnabled(false);
2✔
586
        m_amountSpin->setEnabled(false);
2✔
587
        m_gapSpin->setEnabled(false);
2✔
588
        m_channelsSpin->setEnabled(false);
2✔
589

590
        m_buttonBox->setStandardButtons(QDialogButtonBox::Cancel);
2✔
591

592
        return;
2✔
593
    }
594

595
    /* Item & its parent should be valid here */
596
    QString manuf(item->parent()->text(KColumnName));
15✔
597
    QString model(item->text(KColumnName));
15✔
598
    if (manuf == KXMLFixtureGeneric && model == KXMLFixtureGeneric)
15✔
599
    {
600
        /* Generic dimmer selected. User enters number of channels. */
601
        if (m_fixtureID != Fixture::invalidId())
13✔
602
        {
603
            Fixture *fxi = m_doc->fixture(m_fixtureID);
1✔
604
            if (fxi != NULL)
1✔
605
            {
606
                m_fixtureDef = fxi->fixtureDef();
1✔
607
                m_mode = fxi->fixtureMode();
1✔
608

609
                if (m_fixtureDef->manufacturer() != manuf || m_fixtureDef->model() != model)
3✔
610
                {
611
                    m_fixtureDef = NULL;
×
612
                }
613
            }
614
            else
615
            {
616
                m_fixtureDef = NULL;
×
617
            }
618
        }
619
        else
620
        {
621
            m_fixtureDef = NULL;
12✔
622
        }
623
        fillModeCombo();
13✔
624
        m_modeCombo->setEnabled(false);
13✔
625
        m_channelsSpin->setValue(1);
13✔
626
        m_channelsSpin->setEnabled(true);
13✔
627
        m_channelList->clear();
13✔
628

629
        /* Set the model name as the fixture's friendly name ONLY
630
           if the user hasn't modified the friendly name field. */
631
        if (m_nameEdit->isModified() == false)
13✔
632
        {
633
            m_nameEdit->setText(tr("Dimmers"));
13✔
634
            slotNameEdited(m_nameEdit->text());
13✔
635
            m_nameEdit->setModified(false);
13✔
636
        }
637
        m_nameEdit->setEnabled(true);
13✔
638
    }
639
    else
640
    {
641
        /* Specific fixture definition selected. */
642
        m_fixtureDef = m_doc->fixtureDefCache()->fixtureDef(manuf, model);
2✔
643
        Q_ASSERT(m_fixtureDef != NULL);
644

645
        /* Put fixture def's modes to the mode combo */
646
        fillModeCombo();
2✔
647

648
        /* Fixture def contains number of channels, so disable the
649
           spin box to prevent user from modifying it. */
650
        m_channelsSpin->setEnabled(false);
2✔
651

652
        /* Set the model name as the fixture's friendly name ONLY
653
           if the user hasn't modified the friendly name field. */
654
        if (m_nameEdit->isModified() == false)
2✔
655
        {
656
            m_nameEdit->setText(m_fixtureDef->model());
2✔
657
            slotNameEdited(m_nameEdit->text());
2✔
658
            m_nameEdit->setModified(false);
2✔
659
        }
660
        m_nameEdit->setEnabled(true);
2✔
661
    }
662

663
    /* Set the maximum number of fixtures */
664
    updateMaximumAmount();
15✔
665

666
    /* Guide the user to edit the friendly name field */
667
    m_nameEdit->setSelection(0, m_nameEdit->text().length());
15✔
668
    m_nameEdit->setFocus();
15✔
669

670
    m_addressSpin->setEnabled(true);
15✔
671
    m_universeCombo->setEnabled(true);
15✔
672

673
    m_multipleGroup->setEnabled(true);
15✔
674
    m_amountSpin->setEnabled(true);
15✔
675
    m_gapSpin->setEnabled(true);
15✔
676

677
    /* Recalculate the first available address for the newly selected fixture */
678
    quint32 addr = findAddress(m_universeValue, m_channelsSpin->value(), m_doc->fixtures(), m_fixtureID);
15✔
679
    if (addr != QLCChannel::invalid())
15✔
680
        m_addressSpin->setValue((addr & 0x01FF) + 1);
15✔
681
    else
682
        m_addressSpin->setValue(1);
×
683

684
    /* OK is again possible */
685
    m_buttonBox->setStandardButtons(QDialogButtonBox::Ok |
15✔
686
                                    QDialogButtonBox::Cancel);
687
}
15✔
688

689
void AddFixture::slotTreeDoubleClicked(QTreeWidgetItem* item)
×
690
{
691
    /* Select and accept (click OK for the user) */
692
    slotSelectionChanged();
×
693
    if (item != NULL && item->parent() != NULL)
×
694
        accept();
×
695
}
×
696

697
void AddFixture::slotDiptoolButtonClicked()
×
698
{
699
    AddressTool at(this, m_addressSpin->value());
×
700
    at.exec();
×
701
    m_addressSpin->setValue(at.getAddress());
×
702
}
×
703

704
void AddFixture::checkOverlapping()
13✔
705
{
706
    for (int i = 0; i < m_amountValue; ++i)
26✔
707
    {
708
        int address = m_addressValue + i * (m_gapValue + m_channelsValue);
13✔
709
        int absAddress = (address & 0x01FF) | (m_universeValue << 9);
13✔
710
        if (checkAddressAvailability(absAddress, m_channelsValue) == false)
13✔
711
        {
712
            // Show overlapping error
713
            m_addrErrorLabel->show();
×
714
            m_invalidAddressFlag = true;
×
715
            return;
×
716
        }
717
    }
718

719
    m_addrErrorLabel->hide();
13✔
720
    m_invalidAddressFlag = false;
13✔
721
}
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