• 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/inputprofileeditor.cpp
1
/*
2
  Q Light Controller
3
  inputprofileeditor.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 <QTreeWidgetItem>
21
#include <QColorDialog>
22
#include <QInputDialog>
23
#include <QTextBrowser>
24
#include <QTreeWidget>
25
#include <QToolButton>
26
#include <QMessageBox>
27
#include <QPushButton>
28
#include <QTabWidget>
29
#include <QSettings>
30
#include <QCheckBox>
31
#include <QDialog>
32
#include <QTimer>
33
#include <QDebug>
34
#include <QFile>
35
#include <QList>
36
#include <QDir>
37

38
#include "qlcinputprofile.h"
39
#include "qlcchannel.h"
40

41
#include "inputchanneleditor.h"
42
#include "inputprofileeditor.h"
43
#include "inputoutputmap.h"
44
#include "apputil.h"
45

46
#define SETTINGS_GEOMETRY "inputprofileeditor/geometry"
47

48
#define KColumnNumber 0
49
#define KColumnName   1
50
#define KColumnType   2
51
#define KColumnValues 3
52

53
/****************************************************************************
54
 * Initialization
55
 ****************************************************************************/
56

57
InputProfileEditor::InputProfileEditor(QWidget* parent, QLCInputProfile* profile,
×
58
                                       InputOutputMap *ioMap)
×
59
    : QDialog(parent)
60
    , m_ioMap(ioMap)
×
61
    , m_wizardActive(false)
×
62
    , m_latestItem(NULL)
×
63
{
64
    Q_ASSERT(ioMap != NULL);
65

66
    setupUi(this);
×
67

68
    m_midiGroupSettings->setVisible(false);
×
69

70
    connect(m_typeCombo, SIGNAL(currentIndexChanged(int)),
×
71
            this, SLOT(slotTypeComboChanged(int)));
72

73
    /* Connect the buttons to slots */
74
    connect(m_addButton, SIGNAL(clicked()),
×
75
            this, SLOT(slotAddClicked()));
76
    connect(m_removeButton, SIGNAL(clicked()),
×
77
            this, SLOT(slotRemoveClicked()));
78
    connect(m_editButton, SIGNAL(clicked()),
×
79
            this, SLOT(slotEditClicked()));
80
    connect(m_wizardButton, SIGNAL(clicked(bool)),
×
81
            this, SLOT(slotWizardClicked(bool)));
82
    connect(m_tree, SIGNAL(itemClicked(QTreeWidgetItem*,int)),
×
83
            this, SLOT(slotItemClicked(QTreeWidgetItem*,int)));
84
    connect(m_tree, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)),
×
85
            this, SLOT(slotEditClicked()));
86
    connect(m_movementCombo, SIGNAL(currentIndexChanged(int)),
×
87
            this, SLOT(slotMovementComboChanged(int)));
88
    connect(m_sensitivitySpin, SIGNAL(valueChanged(int)),
×
89
            this, SLOT(slotSensitivitySpinChanged(int)));
90
    connect(m_extraPressCheck, SIGNAL(toggled(bool)),
×
91
            this, SLOT(slotExtraPressChecked(bool)));
92
    connect(m_lowerSpin, SIGNAL(valueChanged(int)),
×
93
            this, SLOT(slotLowerValueSpinChanged(int)));
94
    connect(m_upperSpin, SIGNAL(valueChanged(int)),
×
95
            this, SLOT(slotUpperValueSpinChanged(int)));
96
    connect(m_midiChannelCombo, SIGNAL(currentIndexChanged(int)),
×
97
            this, SLOT(slotMidiChannelComboChanged(int)));
98

99
    connect(m_addColorButton, SIGNAL(clicked()),
×
100
            this, SLOT(slotAddColor()));
101
    connect(m_removeColorButton, SIGNAL(clicked()),
×
102
            this, SLOT(slotRemoveColor()));
103

104
    connect(m_addMidiChannelButton, SIGNAL(clicked()),
×
105
            this, SLOT(slotAddMidiChannel()));
106
    connect(m_removeMidiChannelButton, SIGNAL(clicked()),
×
107
            this, SLOT(slotRemoveMidiChannel()));
108

109
    /* Listen to input data */
110
    connect(m_ioMap, SIGNAL(inputValueChanged(quint32, quint32, uchar, const QString&)),
×
111
            this, SLOT(slotInputValueChanged(quint32, quint32, uchar, const QString&)));
112

113
    if (profile == NULL)
×
114
    {
115
        m_profile = new QLCInputProfile();
×
116
    }
117
    else
118
    {
119
        m_profile = profile->createCopy();
×
120
        if ((QFile::permissions(m_profile->path()) &
×
121
                QFile::WriteUser) == 0)
122
        {
123
            QMessageBox::warning(this, tr("File not writable"),
×
124
                                 tr("You do not have permission to write to "
×
125
                                    "the file %1. You might not be able to "
126
                                    "save your modifications to the profile.")
127
                                 .arg(QDir::toNativeSeparators(
×
128
                                          m_profile->path())));
×
129
        }
130
    }
131

132
    QList<QLCInputProfile::Type> types = QLCInputProfile::types();
×
133
    for (int i = 0; i < types.size(); ++i)
×
134
    {
135
        const QLCInputProfile::Type type = types.at(i);
×
136
        m_typeCombo->addItem(QLCInputProfile::typeToString(type), type);
×
137
        if (m_profile->type() == type)
×
138
        {
139
            m_typeCombo->setCurrentIndex(i);
×
140
            if (type == QLCInputProfile::MIDI)
×
141
            {
142
                m_midiGroupSettings->setVisible(true);
×
143
                m_noteOffCheck->setChecked(m_profile->midiSendNoteOff());
×
144
            }
145
        }
146
    }
147

148
    /* Profile manufacturer & model */
149
    m_manufacturerEdit->setText(m_profile->manufacturer());
×
150
    m_modelEdit->setText(m_profile->model());
×
151

152
    m_behaviourBox->hide();
×
153
    m_feedbackGroup->hide();
×
154

155
    /* Fill up the tree with profile's channels */
156
    fillTree();
×
157

158
    /* Fill up the tree with color table */
159
    updateColorsTree();
×
160

161
    /* Fill up the tree with MIDI channel table */
162
    updateMidiChannelTree();
×
163

164
    /* Timer that clears the input data icon after a while */
165
    m_timer = new QTimer(this);
×
166
    m_timer->setSingleShot(true);
167
    connect(m_timer, SIGNAL(timeout()), this, SLOT(slotTimerTimeout()));
×
168

169
    QSettings settings;
×
170
    QVariant var = settings.value(SETTINGS_GEOMETRY);
×
171
    if (var.isValid() == true)
×
172
        restoreGeometry(var.toByteArray());
×
173
    AppUtil::ensureWidgetIsVisible(this);
×
174
}
×
175

176
InputProfileEditor::~InputProfileEditor()
×
177
{
178
    QSettings settings;
×
179
    settings.setValue(SETTINGS_GEOMETRY, saveGeometry());
×
180

181
    delete m_profile;
×
182
}
×
183

184
void InputProfileEditor::fillTree()
×
185
{
186
    m_tree->clear();
×
187

188
    QMapIterator <quint32,QLCInputChannel*> it(m_profile->channels());
×
189
    while (it.hasNext() == true)
×
190
    {
191
        it.next();
×
192
        updateChannelItem(new QTreeWidgetItem(m_tree), it.value());
×
193
    }
194
    m_tree->header()->resizeSections(QHeaderView::ResizeToContents);
×
195
}
×
196

197
void InputProfileEditor::updateColorsTree()
×
198
{
199
    m_colorTableTree->clear();
×
200

201
    QMapIterator <uchar, QPair<QString, QColor>> it(m_profile->colorTable());
×
202
    while (it.hasNext() == true)
×
203
    {
204
        it.next();
×
205
        QPair<QString, QColor> lc = it.value();
206
        QTreeWidgetItem *item = new QTreeWidgetItem(m_colorTableTree);
×
207
        item->setText(0, QString::number(it.key()));
×
208
        item->setText(1, lc.first);
×
209

210
        QLabel *colLabel = new QLabel();
×
211
        colLabel->setStyleSheet(QString("background-color: %1").arg(lc.second.name()));
×
212

213
        m_colorTableTree->setItemWidget(item, 2, colLabel);
×
214
    }
215
}
×
216

217
void InputProfileEditor::updateMidiChannelTree()
×
218
{
219
    m_midiChannelsTree->clear();
×
220
    m_midiChannelCombo->clear();
×
221

222
    if (m_profile->hasMidiChannelTable())
×
223
    {
224
        m_midiChannelCombo->show();
×
225
        m_midiChannelLabel->show();
×
226
        m_midiChannelCombo->addItem(tr("From plugin settings"));
×
227
    }
228
    else
229
    {
230
        m_midiChannelCombo->hide();
×
231
        m_midiChannelLabel->hide();
×
232
    }
233

234
    QMapIterator <uchar, QString> it(m_profile->midiChannelTable());
×
235
    while (it.hasNext() == true)
×
236
    {
237
        it.next();
×
238
        QTreeWidgetItem *item = new QTreeWidgetItem(m_midiChannelsTree);
×
239
        item->setText(0, QString::number(it.key() + 1));
×
240
        item->setText(1, it.value());
×
241

242
        m_midiChannelCombo->addItem(it.value());
×
243
    }
244
}
×
245

246
void InputProfileEditor::updateChannelItem(QTreeWidgetItem *item,
×
247
                                           QLCInputChannel *ch)
248
{
249
    quint32 num;
250

251
    Q_ASSERT(item != NULL);
252
    Q_ASSERT(ch != NULL);
253

254
    num = m_profile->channelNumber(ch);
×
255
    item->setText(KColumnNumber, QString("%1").arg(num + 1, 4, 10, QChar('0')));
×
256
    item->setText(KColumnName, ch->name());
×
257
    item->setText(KColumnType, QLCInputChannel::typeToString(ch->type()));
×
258
    item->setIcon(KColumnType, ch->icon());
×
259
}
×
260

261
void InputProfileEditor::setOptionsVisibility(QLCInputChannel::Type type)
×
262
{
263
    bool showBox = true;
264
    bool showMovement = false;
265
    bool showSensitivity = false;
266
    bool showButtonOpts = false;
267

268
    if (type == QLCInputChannel::Slider || type == QLCInputChannel::Knob)
×
269
    {
270
        showMovement = true;
271
        showSensitivity = true;
272
        m_sensitivitySpin->setRange(10, 100);
×
273
    }
274
    else if (type == QLCInputChannel::Encoder)
×
275
    {
276
        showSensitivity = true;
277
        m_sensitivitySpin->setRange(1, 20);
×
278
    }
279
    else if (type == QLCInputChannel::Button)
×
280
    {
281
        showButtonOpts = true;
282
    }
283
    else
284
        showBox = false;
285

286
    m_movementLabel->setVisible(showMovement);
×
287
    m_movementCombo->setVisible(showMovement);
×
288
    m_sensitivityLabel->setVisible(showSensitivity);
×
289
    m_sensitivitySpin->setVisible(showSensitivity);
×
290
    m_extraPressCheck->setVisible(showButtonOpts);
×
291
    m_feedbackGroup->setVisible(showButtonOpts);
×
292
    m_behaviourBox->setVisible(showBox);
×
293
}
×
294

295
void InputProfileEditor::slotTypeComboChanged(int)
×
296
{
297
    bool showMidiSettings = false;
298

299
    if (currentProfileType() == QLCInputProfile::MIDI)
×
300
    {
301
        showMidiSettings = true;
302
        updateMidiChannelTree();
×
303
    }
304

305
    m_midiGroupSettings->setVisible(showMidiSettings);
×
306
}
×
307

308
/****************************************************************************
309
 * OK & Cancel
310
 ****************************************************************************/
311

312
void InputProfileEditor::reject()
×
313
{
314
    /* Don't allow closing the dialog in any way when the wizard is on */
315
    if (m_buttonBox->isEnabled() == false)
×
316
        return;
317

318
    QDialog::reject();
×
319
}
320

321
void InputProfileEditor::accept()
×
322
{
323
    /* Don't allow closing the dialog in any way when the wizard is on */
324
    if (m_buttonBox->isEnabled() == false)
×
325
        return;
326

327
    m_profile->setManufacturer(m_manufacturerEdit->text());
×
328
    m_profile->setModel(m_modelEdit->text());
×
329
    m_profile->setType(currentProfileType());
×
330

331
    if (currentProfileType() == QLCInputProfile::MIDI)
×
332
        m_profile->setMidiSendNoteOff(m_noteOffCheck->isChecked());
×
333

334
    /* Check that we have at least the bare necessities to save the profile */
335
    if (m_profile->manufacturer().isEmpty() == true ||
×
336
        m_profile->model().isEmpty() == true)
×
337
    {
338
        QMessageBox::warning(this, tr("Missing information"),
×
339
                             tr("Manufacturer and/or model name is missing."));
×
340
    }
341
    else
342
    {
343
        QDialog::accept();
×
344
    }
345
}
346

347
/****************************************************************************
348
 * Editing
349
 ****************************************************************************/
350

351
QList<QLCInputChannel *> InputProfileEditor::selectedChannels()
×
352
{
353
    QList<QLCInputChannel *> channels;
354

355
    QListIterator <QTreeWidgetItem*>it(m_tree->selectedItems());
×
356
    while (it.hasNext() == true)
×
357
    {
358
        QTreeWidgetItem *item = it.next();
×
359
        Q_ASSERT(item != NULL);
360

361
        quint32 chnum = item->text(KColumnNumber).toUInt() - 1;
×
362
        QLCInputChannel *channel = m_profile->channel(chnum);
×
363
        Q_ASSERT(channel != NULL);
364

365
        channels.append(channel);
×
366
    }
367
    return channels;
×
368
}
×
369

370
void InputProfileEditor::slotAddClicked()
×
371
{
372
    QLCInputChannel* channel = new QLCInputChannel();
×
373
    InputChannelEditor ice(this, m_profile, channel, currentProfileType());
×
374
add:
×
375
    if (ice.exec() == QDialog::Accepted)
×
376
    {
377
        channel->setType(ice.type());
×
378
        channel->setName(ice.name());
×
379

380
        if (m_profile->channel(ice.channel()) == NULL)
×
381
        {
382
            m_profile->insertChannel(ice.channel(), channel);
×
383
            updateChannelItem(new QTreeWidgetItem(m_tree), channel);
×
384
        }
385
        else
386
        {
387
            QMessageBox::warning(this,
×
388
                                 tr("Channel already exists"),
×
389
                                 tr("Channel %1 already exists")
×
390
                                 .arg(ice.channel() + 1));
×
391
            goto add;
×
392
        }
393
    }
394
    else
395
    {
396
        delete channel;
×
397
    }
398
}
×
399

400
void InputProfileEditor::slotRemoveClicked()
×
401
{
402
    QList <QTreeWidgetItem*> selected;
403
    QTreeWidgetItem* next = NULL;
404

405
    /* Ask for confirmation if we're deleting more than one channel */
406
    selected = m_tree->selectedItems();
×
407
    if (selected.count() > 1)
×
408
    {
409
        int r;
410
        r = QMessageBox::question(this, tr("Delete channels"),
×
411
                                  tr("Delete all %1 selected channels?")
×
412
                                  .arg(selected.count()),
×
413
                                  QMessageBox::Yes | QMessageBox::No);
414
        if (r == QMessageBox::No)
×
415
            return;
416
    }
417

418
    /* Remove all selected channels */
419
    QMutableListIterator <QTreeWidgetItem*> it(selected);
×
420
    while (it.hasNext() == true)
×
421
    {
422
        QTreeWidgetItem *item = it.next();
×
423
        Q_ASSERT(item != NULL);
424

425
        /* Remove & Delete the channel object */
426
        quint32 chnum = item->text(KColumnNumber).toUInt() - 1;
×
427
        m_profile->removeChannel(chnum);
×
428

429
        /* Choose the closest item below or above the removed items
430
           as the one that is selected after the removal */
431
        next = m_tree->itemBelow(item);
×
432
        if (next == NULL)
×
433
            next = m_tree->itemAbove(item);
×
434

435
        delete item;
×
436
    }
437

438
    m_tree->setCurrentItem(next);
×
439
}
×
440

441
void InputProfileEditor::slotEditClicked()
×
442
{
443
    QLCInputChannel* channel;
444
    quint32 chnum;
445
    QTreeWidgetItem* item;
446

447
    if (m_tree->selectedItems().count() == 1)
×
448
    {
449
        /* Just one item selected. Edit that. */
450
        item = m_tree->currentItem();
×
451
        if (item == NULL)
×
452
            return;
×
453

454
        /* Find the channel object associated to the selected item */
455
        chnum = item->text(KColumnNumber).toUInt() - 1;
×
456
        channel = m_profile->channel(chnum);
×
457
        Q_ASSERT(channel != NULL);
458

459
        /* Edit the channel and update its item if necessary */
460
        InputChannelEditor ice(this, m_profile, channel, currentProfileType());
×
461
edit:
×
462
        if (ice.exec() == QDialog::Accepted)
×
463
        {
464
            QLCInputChannel* another;
465
            another = m_profile->channel(ice.channel());
×
466

467
            if (another == NULL || another == channel)
×
468
            {
469
                if (ice.channel() != QLCChannel::invalid())
×
470
                    m_profile->remapChannel(channel, ice.channel());
×
471
                if (ice.name().isEmpty() == false)
×
472
                    channel->setName(ice.name());
×
473
                if (ice.type() != QLCInputChannel::NoType)
×
474
                {
475
                    if (ice.type() != channel->type())
×
476
                        setOptionsVisibility(ice.type());
×
477
                    channel->setType(ice.type());
×
478
                    if (m_sensitivitySpin->isVisible())
×
479
                        m_sensitivitySpin->setValue(channel->movementSensitivity());
×
480
                }
481

482
                updateChannelItem(item, channel);
×
483
            }
484
            else
485
            {
486
                QMessageBox::warning(this,
×
487
                                     tr("Channel already exists"),
×
488
                                     tr("Channel %1 already exists")
×
489
                                     .arg(ice.channel() + 1));
×
490
                goto edit;
×
491
            }
492
        }
493
    }
×
494
    else if (m_tree->selectedItems().count() > 1)
×
495
    {
496
        /* Multiple channels selected. Apply changes to all of them */
497
        InputChannelEditor ice(this, NULL, NULL, QLCInputProfile::DMX);
×
498
        if (ice.exec() == QDialog::Accepted)
×
499
        {
500
            QListIterator <QTreeWidgetItem*>
501
            it(m_tree->selectedItems());
×
502
            while (it.hasNext() == true)
×
503
            {
504
                item = it.next();
×
505
                Q_ASSERT(item != NULL);
506

507
                chnum = item->text(KColumnNumber).toUInt() - 1;
×
508
                channel = m_profile->channel(chnum);
×
509
                Q_ASSERT(channel != NULL);
510

511
                /* Set only name and type and only if they
512
                   have been modified. */
513
                if (ice.name().isEmpty() == false)
×
514
                    channel->setName(ice.name());
×
515
                if (ice.type() != QLCInputChannel::NoType)
×
516
                    channel->setType(ice.type());
×
517

518
                updateChannelItem(item, channel);
×
519
            }
520
        }
521
    }
×
522
}
523

524
void InputProfileEditor::slotWizardClicked(bool checked)
×
525
{
526
    if (checked == true)
×
527
    {
528
        QMessageBox::information(this, tr("Channel wizard activated"),
×
529
                                 tr("You have enabled the input channel wizard. After "
×
530
                                    "clicking OK, wiggle your mapped input profile's "
531
                                    "controls. They should appear into the list. "
532
                                    "Click the wizard button again to stop channel "
533
                                    "auto-detection.\n\nNote that the wizard cannot "
534
                                    "tell the difference between a knob and a slider "
535
                                    "so you will have to do the change manually."));
536
        m_wizardActive = true;
×
537
    }
538
    else
539
    {
540
        m_wizardActive = false;
×
541
    }
542

543
    m_buttonBox->setEnabled(!checked);
×
544
    m_tab->setTabEnabled(0, !checked);
×
545
}
×
546

547
void InputProfileEditor::slotItemClicked(QTreeWidgetItem *item, int col)
×
548
{
549
    Q_UNUSED(col)
550

551
    quint32 chNum = item->text(KColumnNumber).toUInt() - 1;
×
552
    QLCInputChannel *ich = m_profile->channel(chNum);
×
553
    if (ich != NULL)
×
554
    {
555
        setOptionsVisibility(ich->type());
×
556

557
        if (ich->type() == QLCInputChannel::Slider || ich->type() == QLCInputChannel::Knob)
×
558
        {
559
            if (ich->movementType() == QLCInputChannel::Absolute)
×
560
            {
561
                m_movementCombo->setCurrentIndex(0);
×
562
                m_sensitivitySpin->setEnabled(false);
×
563
            }
564
            else
565
            {
566
                m_movementCombo->setCurrentIndex(1);
×
567
                m_sensitivitySpin->setValue(ich->movementSensitivity());
×
568
                m_sensitivitySpin->setEnabled(true);
×
569
            }
570
        }
571
        else if (ich->type() == QLCInputChannel::Encoder)
×
572
        {
573
            m_sensitivitySpin->setValue(ich->movementSensitivity());
×
574
            m_sensitivitySpin->setEnabled(true);
×
575
        }
576
        else if (ich->type() == QLCInputChannel::Button)
×
577
        {
578
            m_extraPressCheck->setChecked(ich->sendExtraPress());
×
579
            m_lowerSpin->blockSignals(true);
×
580
            m_upperSpin->blockSignals(true);
×
581
            m_midiChannelCombo->blockSignals(true);
×
582
            m_lowerSpin->setValue(ich->lowerValue());
×
583
            m_upperSpin->setValue(ich->upperValue());
×
584
            m_midiChannelCombo->setCurrentIndex(ich->lowerChannel() + 1);
×
585
            m_lowerSpin->blockSignals(false);
×
586
            m_upperSpin->blockSignals(false);
×
587
            m_midiChannelCombo->blockSignals(false);
×
588
        }
589
    }
590
    else
591
        setOptionsVisibility(QLCInputChannel::NoType);
×
592
}
×
593

594
void InputProfileEditor::slotMovementComboChanged(int index)
×
595
{
596
    if (index == 1)
×
597
        m_sensitivitySpin->setEnabled(true);
×
598
    else
599
        m_sensitivitySpin->setEnabled(false);
×
600

601
    foreach (QLCInputChannel *channel, selectedChannels())
×
602
    {
603
        if (channel->type() == QLCInputChannel::Slider ||
×
604
            channel->type() == QLCInputChannel::Knob)
×
605
        {
606
            if (index == 1)
×
607
                channel->setMovementType(QLCInputChannel::Relative);
×
608
            else
609
                channel->setMovementType(QLCInputChannel::Absolute);
×
610
        }
611
    }
612
}
×
613

614
void InputProfileEditor::slotSensitivitySpinChanged(int value)
×
615
{
616
    foreach (QLCInputChannel *channel, selectedChannels())
×
617
    {
618
        if ((channel->type() == QLCInputChannel::Slider ||
×
619
             channel->type() == QLCInputChannel::Knob) &&
×
620
            channel->movementType() == QLCInputChannel::Relative)
×
621
                channel->setMovementSensitivity(value);
×
622
        else if (channel->type() == QLCInputChannel::Encoder)
×
623
            channel->setMovementSensitivity(value);
×
624
    }
625
}
×
626

627
void InputProfileEditor::slotExtraPressChecked(bool checked)
×
628
{
629
    foreach (QLCInputChannel *channel, selectedChannels())
×
630
    {
631
        if (channel->type() == QLCInputChannel::Button)
×
632
            channel->setSendExtraPress(checked);
×
633
    }
634
}
×
635

636
void InputProfileEditor::slotLowerValueSpinChanged(int value)
×
637
{
638
    foreach (QLCInputChannel *channel, selectedChannels())
×
639
    {
640
        if (channel->type() == QLCInputChannel::Button)
×
641
            channel->setRange(uchar(value), uchar(m_upperSpin->value()));
×
642
    }
643
}
×
644

645
void InputProfileEditor::slotUpperValueSpinChanged(int value)
×
646
{
647
    foreach (QLCInputChannel *channel, selectedChannels())
×
648
    {
649
        if (channel->type() == QLCInputChannel::Button)
×
650
            channel->setRange(uchar(m_lowerSpin->value()), uchar(value));
×
651
    }
652
}
×
653

654
void InputProfileEditor::slotMidiChannelComboChanged(int index)
×
655
{
656
    foreach (QLCInputChannel *channel, selectedChannels())
×
657
    {
658
        if (channel->type() == QLCInputChannel::Button)
×
659
            channel->setLowerChannel(index - 1);
×
660
    }
661
}
×
662

663
void InputProfileEditor::slotAddColor()
×
664
{
665
    bool ok;
666
    int val = QInputDialog::getInt(this, tr("Enter value"), tr("Feedback value"), 0, 0, 255, 1, &ok);
×
667

668
    if (ok)
×
669
    {
670
        QColor color = QColorDialog::getColor();
×
671

672
        QString label = QInputDialog::getText(this, tr("Enter label"), tr("Color label"));
×
673
        m_profile->addColor(val, label, color);
×
674
        updateColorsTree();
×
675
        m_colorTableTree->scrollToBottom();
×
676
    }
×
677
}
×
678

679
void InputProfileEditor::slotRemoveColor()
×
680
{
681
    foreach (QTreeWidgetItem *item, m_colorTableTree->selectedItems())
×
682
    {
683
        uchar value = uchar(item->text(0).toInt());
×
684
        m_profile->removeColor(value);
×
685
    }
686
    updateColorsTree();
×
687
}
×
688

689
void InputProfileEditor::slotAddMidiChannel()
×
690
{
691
    bool ok;
692
    int val = QInputDialog::getInt(this, tr("Enter value"), tr("MIDI channel"), 1, 1, 16, 1, &ok);
×
693

694
    if (ok)
×
695
    {
696
        QString label = QInputDialog::getText(this, tr("Enter label"), tr("MIDI channel label"));
×
697
        m_profile->addMidiChannel(val - 1, label);
×
698
        updateMidiChannelTree();
×
699
    }
×
700
}
×
701

702
void InputProfileEditor::slotRemoveMidiChannel()
×
703
{
704
    foreach (QTreeWidgetItem *item, m_midiChannelsTree->selectedItems())
×
705
    {
706
        uchar value = uchar(item->text(0).toInt());
×
707
        m_profile->removeMidiChannel(value);
×
708
    }
709
    updateMidiChannelTree();
×
710
}
×
711

712
void InputProfileEditor::slotInputValueChanged(quint32 universe,
×
713
                                               quint32 channel,
714
                                               uchar value,
715
                                               const QString& key)
716
{
717
    QTreeWidgetItem* latestItem = NULL;
718

719
    Q_UNUSED(universe);
720

721
    /* Get a list of items that represent the given channel. Basically
722
       the list should always contain just one item. */
723
    QList <QTreeWidgetItem*> list;
724
    if (channel == UINT_MAX && key.isEmpty() == false)
×
725
        list = m_tree->findItems(key, Qt::MatchExactly, KColumnName);
×
726
    else
727
        list = m_tree->findItems(QString("%1").arg(channel + 1, 4, 10, QChar('0')), Qt::MatchExactly,
×
728
                             KColumnNumber);
729
    if (list.size() != 0)
×
730
        latestItem = list.first();
×
731

732
    if (list.size() == 0 && m_wizardActive == true)
×
733
    {
734
        /* No channel items found. Create a new channel to the
735
           profile and display it also in the tree widget */
736
        QLCInputChannel* ch = new QLCInputChannel();
×
737
        if (key.isEmpty())
×
738
            ch->setName(tr("Button %1").arg(channel + 1));
×
739
        else
740
            ch->setName(key);
×
741
        ch->setType(QLCInputChannel::Button);
×
742
        m_profile->insertChannel(channel, ch);
×
743

744
        latestItem = new QTreeWidgetItem(m_tree);
×
745
        updateChannelItem(latestItem, ch);
×
746
    }
747
    else if (m_wizardActive == true)
×
748
    {
749
        /* Existing channel & item found. Modify their contents. */
750
        latestItem = list.first();
×
751
        QVariant var = latestItem->data(KColumnValues, Qt::UserRole);
×
752
        QStringList values(var.toStringList());
×
753

754
        if (values.size() > 3)
×
755
        {
756
            /* No need to collect any more values, since this channel has
757
               been judged to be a slider when count == 3 (see below). */
758
        }
759
        else if (values.contains(QString("%1").arg(value)) == false)
×
760
        {
761
            values << QString("%1").arg(value);
×
762
            values.sort();
763
            latestItem->setData(KColumnValues, Qt::UserRole, values);
×
764
        }
765

766
        /* Change the channel type only the one time when its value
767
           count goes over 2. I.e. when a channel can have more than
768
           two distinct values, it can no longer be a button. */
769
        if (values.size() == 3)
×
770
        {
771
            QLCInputChannel* ch = m_profile->channel(channel);
×
772
            Q_ASSERT(ch != NULL);
773

774
            if (ch->type() == QLCInputChannel::Button)
×
775
            {
776
                ch->setType(QLCInputChannel::Slider);
×
777
                if (key.isEmpty())
×
778
                    ch->setName(tr("Slider %1").arg(channel + 1));
×
779
                else
780
                    ch->setName(key);
×
781
                updateChannelItem(latestItem, ch);
×
782
            }
783
        }
784
    }
×
785

786
    if (latestItem != NULL)
×
787
    {
788
        if (m_latestItem != NULL)
×
789
            m_latestItem->setIcon(KColumnNumber, QIcon());
×
790
        m_latestItem = latestItem;
×
791
        m_latestItem->setIcon(KColumnNumber, QIcon(":/input.png"));
×
792
        m_tree->scrollToItem(m_latestItem);
×
793
        m_timer->start(250);
×
794
    }
795
}
×
796

797
void InputProfileEditor::slotTimerTimeout()
×
798
{
799
    if (m_latestItem != NULL)
×
800
        m_latestItem->setIcon(KColumnNumber, QIcon());
×
801
    m_latestItem = NULL;
×
802
}
×
803

804
/****************************************************************************
805
 * Profile
806
 ****************************************************************************/
807

808
QLCInputProfile* InputProfileEditor::profile()
×
809
{
810
    return m_profile;
×
811
}
812

813
QLCInputProfile::Type InputProfileEditor::currentProfileType() const
×
814
{
815
    return static_cast<QLCInputProfile::Type>(m_typeCombo->itemData(m_typeCombo->currentIndex()).toInt());
×
816
}
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