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

mcallegari / qlcplus / 8961243534

05 May 2024 09:23PM UTC coverage: 32.068% (+4.0%) from 28.094%
8961243534

push

github

mcallegari
Merge branch 'master' into qmltoqt6

902 of 2557 new or added lines in 140 files covered. (35.28%)

166 existing lines in 76 files now uncovered.

15395 of 48008 relevant lines covered (32.07%)

22949.67 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

UNCOV
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)));
NEW
96
    connect(m_midiChannelCombo, SIGNAL(currentIndexChanged(int)),
×
97
            this, SLOT(slotMidiChannelComboChanged(int)));
98

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

NEW
104
    connect(m_addMidiChannelButton, SIGNAL(clicked()),
×
105
            this, SLOT(slotAddMidiChannel()));
NEW
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
    {
NEW
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 */
NEW
159
    updateColorsTree();
×
160

161
    /* Fill up the tree with MIDI channel table */
NEW
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

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

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

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

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

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

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

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

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

NEW
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
{
NEW
297
    bool showMidiSettings = false;
×
298

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

NEW
305
    m_midiGroupSettings->setVisible(showMidiSettings);
×
UNCOV
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 ||
×
NEW
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);
×
NEW
581
            m_midiChannelCombo->blockSignals(true);
×
582
            m_lowerSpin->setValue(ich->lowerValue());
×
583
            m_upperSpin->setValue(ich->upperValue());
×
NEW
584
            m_midiChannelCombo->setCurrentIndex(ich->lowerChannel() + 1);
×
585
            m_lowerSpin->blockSignals(false);
×
586
            m_upperSpin->blockSignals(false);
×
NEW
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

NEW
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
{
NEW
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
{
NEW
629
    foreach (QLCInputChannel *channel, selectedChannels())
×
630
    {
NEW
631
        if (channel->type() == QLCInputChannel::Button)
×
632
            channel->setSendExtraPress(checked);
×
633
    }
634
}
×
635

636
void InputProfileEditor::slotLowerValueSpinChanged(int value)
×
637
{
NEW
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
{
NEW
647
    foreach (QLCInputChannel *channel, selectedChannels())
×
648
    {
649
        if (channel->type() == QLCInputChannel::Button)
×
650
            channel->setRange(uchar(m_lowerSpin->value()), uchar(value));
×
651
    }
652
}
×
653

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

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

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

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

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

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

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

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

UNCOV
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();
×
NEW
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);
×
NEW
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

NEW
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