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

mcallegari / qlcplus / 11549478814

28 Oct 2024 07:43AM UTC coverage: 31.983% (+0.003%) from 31.98%
11549478814

push

github

web-flow
actions: bump macos runner version

14033 of 43877 relevant lines covered (31.98%)

27056.43 hits per line

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

88.75
/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;
14✔
145
    QVariant var = settings.value(SETTINGS_GEOMETRY);
21✔
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;
14✔
157
    settings.setValue(SETTINGS_GEOMETRY, saveGeometry());
7✔
158

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

162
    for (int i=0; i < root->childCount(); i++)
980✔
163
    {
164
        QTreeWidgetItem * manuf = root->child(i);
973✔
165
        if (manuf->isExpanded())
973✔
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;
7✔
233
    QString model;
7✔
234
    QList<QVariant> expanded;
7✔
235

236
    QSettings settings;
14✔
237
    QVariant var = settings.value(SETTINGS_EXPANDED);
21✔
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();
14✔
247

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

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

258
        QStringListIterator modit(m_doc->fixtureDefCache()->models(manuf));
1,932✔
259
        while (modit.hasNext() == true)
11,851✔
260
        {
261
            model = modit.next();
10,885✔
262

263
            if (filter.isEmpty() == false &&
10,885✔
264
                manuf.toLower().contains(filter) == false &&
21,770✔
265
                model.toLower().contains(filter) == false)
10,885✔
266
                    continue;
×
267

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

277
            if (manuf == selectManufacturer &&
10,953✔
278
                    model == selectModel)
68✔
279
            {
280
                parent->setExpanded(true);
1✔
281
                m_tree->setCurrentItem(child);
1✔
282
            }
283
            else if (expanded.indexOf(manuf) != -1)
21,768✔
284
            {
285
                parent->setExpanded(true);
277✔
286
            }
287
            m_fxiCount++;
10,885✔
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);
28✔
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());
6✔
348
        while (it.hasNext() == true)
12✔
349
            m_modeCombo->addItem(it.next()->name());
18✔
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);
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
            map[(fxi->universeAddress() & 0x01FF) + ch] = 1;
410✔
412
    }
413

414
    /* Try to find the next contiguous free address space */
415
    for (quint32 addr = 0; addr < maxChannels; addr++)
6,082✔
416
    {
417
        if (map[addr] == 0)
6,073✔
418
            freeSpace++;
5,798✔
419
        else
420
            freeSpace = 0;
421

422
        if (freeSpace == numChannels)
6,073✔
423
            return (addr - freeSpace + 1) | (universe << 9);
43✔
424
    }
425

426
    return QLCChannel::invalid();
61✔
427
}
428

429
void AddFixture::updateMaximumAmount()
28✔
430
{
431
    m_amountSpin->setRange(1, (513 - m_addressSpin->value()) /
28✔
432
                           (m_channelsSpin->value() + m_gapSpin->value()));
28✔
433
}
28✔
434

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

447
/*****************************************************************************
448
 * Slots
449
 *****************************************************************************/
450

451
void AddFixture::slotModeActivated(int modeIndex)
5✔
452
{
453
    if (m_fixtureDef == NULL)
5✔
454
        return;
455

456
    m_mode = m_fixtureDef->modes().at(modeIndex);
5✔
457
    if (m_mode == NULL)
5✔
458
    {
459
        /* Generic dimmers don't have modes, so bail out */
460
        // slotSelectionChanged();
461
        return;
462
    }
463

464
    m_channelsSpin->setValue(m_mode->channels().size());
5✔
465

466
    /* Show all selected mode channels in the list */
467
    m_channelList->clear();
5✔
468
    for (int i = 0; i < m_mode->channels().size(); i++)
44✔
469
    {
470
        QLCChannel* channel = m_mode->channel(i);
39✔
471
        Q_ASSERT(channel != NULL);
472

473
        new QListWidgetItem(
474
            QString("%1: %2").arg(i + 1).arg(channel->name()),
78✔
475
            m_channelList);
39✔
476
    }
477
}
478

479
void AddFixture::slotUniverseActivated(int universe)
7✔
480
{
481
    m_universeValue = universe;
7✔
482

483
    /* Adjust the available address range */
484
    slotChannelsChanged(m_channelsValue);
7✔
485

486
    quint32 addr = findAddress(universe, m_channelsSpin->value(), m_doc->fixtures(), m_fixtureID);
7✔
487
    if (addr != QLCChannel::invalid())
7✔
488
        m_addressSpin->setValue((addr & 0x01FF) + 1);
7✔
489
    else
490
        m_addressSpin->setValue(1);
×
491
}
7✔
492

493
void AddFixture::slotAddressChanged(int value)
2✔
494
{
495
    m_addressValue = value - 1;
2✔
496

497
    /* Set the maximum number of fixtures */
498
    updateMaximumAmount();
2✔
499

500
    checkOverlapping();
2✔
501
}
2✔
502

503
void AddFixture::slotChannelsChanged(int value)
11✔
504
{
505
    m_channelsValue = value;
11✔
506

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

511
    /* Set the maximum number of fixtures */
512
    updateMaximumAmount();
11✔
513

514
    checkOverlapping();
11✔
515
}
11✔
516

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

528
void AddFixture::slotAmountSpinChanged(int value)
×
529
{
530
    m_amountValue = value;
×
531

532
    checkOverlapping();
×
533
}
×
534

535
void AddFixture::slotGapSpinChanged(int value)
×
536
{
537
    m_gapValue = value;
×
538

539
    /* Set the maximum number of fixtures */
540
    updateMaximumAmount();
×
541

542
    checkOverlapping();
×
543
}
×
544

545
void AddFixture::slotSearchFilterChanged(QString)
×
546
{
547
    m_tree->blockSignals(true);
×
548
    fillTree("", "");
×
549
    m_tree->blockSignals(false);
×
550
}
×
551

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

562
        /* Since there is no m_fixtureDef, mode combo is cleared */
563
        fillModeCombo();
2✔
564

565
        /* Clear the name box unless it has been modified by user */
566
        if (m_nameEdit->isModified() == false)
2✔
567
        {
568
            m_nameEdit->setText(QString());
2✔
569
            slotNameEdited(QString());
2✔
570
            m_nameEdit->setModified(false);
2✔
571
        }
572
        m_nameEdit->setEnabled(false);
2✔
573

574
        m_channelsSpin->setValue(0);
2✔
575
        m_channelList->clear();
2✔
576
        m_addressSpin->setEnabled(false);
2✔
577
        m_universeCombo->setEnabled(false);
2✔
578

579
        m_multipleGroup->setEnabled(false);
2✔
580
        m_amountSpin->setEnabled(false);
2✔
581
        m_gapSpin->setEnabled(false);
2✔
582
        m_channelsSpin->setEnabled(false);
2✔
583

584
        m_buttonBox->setStandardButtons(QDialogButtonBox::Cancel);
2✔
585

586
        return;
2✔
587
    }
588

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

603
                if (m_fixtureDef->manufacturer() != manuf || m_fixtureDef->model() != model)
3✔
604
                {
605
                    m_fixtureDef = NULL;
×
606
                }
607
            }
608
            else
609
            {
610
                m_fixtureDef = NULL;
×
611
            }
612
        }
613
        else
614
        {
615
            m_fixtureDef = NULL;
12✔
616
        }
617
        fillModeCombo();
13✔
618
        m_modeCombo->setEnabled(false);
13✔
619
        m_channelsSpin->setValue(1);
13✔
620
        m_channelsSpin->setEnabled(true);
13✔
621
        m_channelList->clear();
13✔
622

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

639
        /* Put fixture def's modes to the mode combo */
640
        fillModeCombo();
2✔
641

642
        /* Fixture def contains number of channels, so disable the
643
           spin box to prevent user from modifying it. */
644
        m_channelsSpin->setEnabled(false);
2✔
645

646
        /* Set the model name as the fixture's friendly name ONLY
647
           if the user hasn't modified the friendly name field. */
648
        if (m_nameEdit->isModified() == false)
2✔
649
        {
650
            m_nameEdit->setText(m_fixtureDef->model());
2✔
651
            slotNameEdited(m_nameEdit->text());
2✔
652
            m_nameEdit->setModified(false);
2✔
653
        }
654
        m_nameEdit->setEnabled(true);
2✔
655
    }
656

657
    /* Set the maximum number of fixtures */
658
    updateMaximumAmount();
15✔
659

660
    /* Guide the user to edit the friendly name field */
661
    m_nameEdit->setSelection(0, m_nameEdit->text().length());
15✔
662
    m_nameEdit->setFocus();
15✔
663

664
    m_addressSpin->setEnabled(true);
15✔
665
    m_universeCombo->setEnabled(true);
15✔
666

667
    m_multipleGroup->setEnabled(true);
15✔
668
    m_amountSpin->setEnabled(true);
15✔
669
    m_gapSpin->setEnabled(true);
15✔
670

671
    /* Recalculate the first available address for the newly selected fixture */
672
    quint32 addr = findAddress(m_universeValue, m_channelsSpin->value(), m_doc->fixtures(), m_fixtureID);
15✔
673
    if (addr != QLCChannel::invalid())
15✔
674
        m_addressSpin->setValue((addr & 0x01FF) + 1);
15✔
675
    else
676
        m_addressSpin->setValue(1);
×
677

678
    /* OK is again possible */
679
    m_buttonBox->setStandardButtons(QDialogButtonBox::Ok |
15✔
680
                                    QDialogButtonBox::Cancel);
681
}
682

683
void AddFixture::slotTreeDoubleClicked(QTreeWidgetItem* item)
×
684
{
685
    /* Select and accept (click OK for the user) */
686
    slotSelectionChanged();
×
687
    if (item != NULL && item->parent() != NULL)
×
688
        accept();
×
689
}
×
690

691
void AddFixture::slotDiptoolButtonClicked()
×
692
{
693
    AddressTool at(this, m_addressSpin->value());
×
694
    at.exec();
×
695
    m_addressSpin->setValue(at.getAddress());
×
696
}
×
697

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

713
    m_addrErrorLabel->hide();
13✔
714
    m_invalidAddressFlag = false;
13✔
715
}
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