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

mcallegari / qlcplus / 14547173229

19 Apr 2025 07:57AM UTC coverage: 31.866% (-0.004%) from 31.87%
14547173229

push

github

web-flow
Merge pull request #1726 from shaforostoff/foreach_optimize

Speed up many foreach-based iterations over QMap

26 of 55 new or added lines in 23 files covered. (47.27%)

1 existing line in 1 file now uncovered.

14684 of 46080 relevant lines covered (31.87%)

26448.78 hits per line

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

0.0
/ui/src/sceneeditor.cpp
1
/*
2
  Q Light Controller
3
  sceneeditor.cpp
4

5
  Copyright (c) Heikki Junnila, Stefan Krumm
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 <QTreeWidget>
23
#include <QMessageBox>
24
#include <QToolButton>
25
#include <QScrollArea>
26
#include <QTabWidget>
27
#include <QComboBox>
28
#include <QSettings>
29
#include <QLineEdit>
30
#include <QToolBar>
31
#include <QLayout>
32
#include <qmath.h>
33
#include <QLabel>
34
#include <QDebug>
35

36
#include "genericdmxsource.h"
37
#include "fixtureselection.h"
38
#include "speeddialwidget.h"
39
#include "functionmanager.h"
40
#include "fixtureconsole.h"
41
#include "groupsconsole.h"
42
#include "qlcfixturedef.h"
43
#include "channelsgroup.h"
44
#include "qlcclipboard.h"
45
#include "positiontool.h"
46
#include "sceneeditor.h"
47
#include "qlcchannel.h"
48
#include "chaserstep.h"
49
#include "fixture.h"
50
#include "chaser.h"
51
#include "scene.h"
52
#include "doc.h"
53

54
#define KColumnName         0
55
#define KColumnManufacturer 1
56
#define KColumnModel        2
57
#define KColumnID           3
58

59
#define KTabGeneral         0
60

61
#define SETTINGS_CHASER "sceneeditor/chaser"
62

63
#define UI_STATE_TAB_INDEX "tabIndex"
64
#define UI_STATE_TAB_MODE  "tabMode"
65
#define UI_STATE_SHOW_DIAL "showDial"
66
#define UI_STATE_TABBED_FIXTURES  0
67
#define UI_STATE_ALL_FIXTURES     1
68

69
SceneEditor::SceneEditor(QWidget* parent, Scene* scene, Doc* doc, bool applyValues)
×
70
    : QWidget(parent)
71
    , m_doc(doc)
×
72
    , m_scene(scene)
×
73
    , m_source(NULL)
×
74
    , m_initFinished(false)
×
75
    , m_speedDials(NULL)
×
76
    , m_channelGroupsTab(-1)
×
77
    , m_currentTab(KTabGeneral)
×
78
    , m_fixtureFirstTabIndex(1)
×
79
    , m_copyFromSelection(false)
×
80
{
81
    qDebug() << Q_FUNC_INFO;
82

83
    Q_ASSERT(doc != NULL);
84
    Q_ASSERT(scene != NULL);
85

86
    setupUi(this);
×
87

88
    init(applyValues);
×
89

90
    // Start new (==empty) scenes from the first tab and ones with something in them
91
    // on the first fixture page.
92
    if (m_tab->count() == 0)
×
93
        slotTabChanged(KTabGeneral);
×
94
    else
95
    {
96
        QVariant tabIndex = scene->uiStateValue(UI_STATE_TAB_INDEX);
×
97
        if (tabIndex.isValid())
×
98
            m_tab->setCurrentIndex(tabIndex.toInt());
×
99
        else
100
            m_tab->setCurrentIndex(0);
×
101
    }
×
102

103
    QVariant showDial = scene->uiStateValue(UI_STATE_SHOW_DIAL);
×
104
    if (showDial.isNull() == false && showDial.toBool() == true)
×
105
        m_speedDialAction->setChecked(true);
×
106

107
    connect(m_doc, SIGNAL(fixtureRemoved(quint32)), this, SLOT(slotFixtureRemoved(quint32)));
×
108

109
    m_initFinished = true;
×
110

111
    // Set focus to the editor
112
    m_nameEdit->setFocus();
×
113
}
×
114

115
SceneEditor::~SceneEditor()
×
116
{
117
    qDebug() << Q_FUNC_INFO;
118

119
    delete m_source;
×
120

121
    QSettings settings;
×
122
    quint32 id = m_chaserCombo->itemData(m_chaserCombo->currentIndex()).toUInt();
×
123
    settings.setValue(SETTINGS_CHASER, id);
×
124
}
×
125

126
void SceneEditor::slotFunctionManagerActive(bool active)
×
127
{
128
    qDebug() << Q_FUNC_INFO;
129

130
    if (active == true)
×
131
    {
132
        if (m_speedDialAction->isChecked() && m_speedDials == NULL)
×
133
            createSpeedDials();
×
134
    }
135
    else
136
    {
137
        if (m_speedDials != NULL)
×
138
            m_speedDials->deleteLater();
×
139
        m_speedDials = NULL;
×
140
    }
141
}
×
142

143
void SceneEditor::slotSetSceneValues(QList <SceneValue>&sceneValues)
×
144
{
145
    QListIterator <SceneValue> it(sceneValues);
×
146

147
    while (it.hasNext() == true)
×
148
    {
149
        SceneValue sv(it.next());
×
150

151
        Fixture *fixture = m_doc->fixture(sv.fxi);
×
152
        Q_ASSERT(fixture != NULL);
153

154
        FixtureConsole *fc = fixtureConsole(fixture);
×
155
        if (fc != NULL)
×
156
            fc->setSceneValue(sv);
×
157
    }
×
158
}
×
159

160
void SceneEditor::slotFixtureRemoved(quint32 id)
×
161
{
162
    removeFixtureTab(id);
×
163
    removeFixtureItem(id);
×
164

165
    QListIterator <SceneValue> it(m_scene->values());
×
166

167
    while (it.hasNext() == true)
×
168
    {
169
        SceneValue sv(it.next());
×
170
        if (sv.fxi == id)
×
171
            m_scene->unsetValue(id, sv.channel);
×
172
    }
×
173
    m_scene->removeFixture(id);
×
174
}
×
175

176
void SceneEditor::init(bool applyValues)
×
177
{
178
    QVariant tabMode = m_scene->uiStateValue(UI_STATE_TAB_MODE);
×
179

180
    this->layout()->setContentsMargins(8, 3, 8, 3);
×
181

182
    /* Actions */
183
    m_enableCurrentAction = new QAction(QIcon(":/check.png"),
×
184
                                        tr("Enable all channels in current fixture"), this);
×
185
    m_disableCurrentAction = new QAction(QIcon(":/uncheck.png"),
×
186
                                         tr("Disable all channels in current fixture"), this);
×
187
    m_copyAction = new QAction(QIcon(":/editcopy.png"),
×
188
                               tr("Copy current values to clipboard"), this);
×
189
    m_pasteAction = new QAction(QIcon(":/editpaste.png"),
×
190
                                tr("Paste clipboard values to current fixture"), this);
×
191
    m_copyToAllAction = new QAction(QIcon(":/editcopyall.png"),
×
192
                                    tr("Copy current values to all fixtures"), this);
×
193
    m_colorToolAction = new QAction(QIcon(":/color.png"),
×
194
                                    tr("Color tool for CMY/RGB-capable fixtures"), this);
×
195
    m_positionToolAction = new QAction(QIcon(":/xypad.png"),
×
196
                                    tr("Position tool for moving heads/scanners"), this);
×
197
    m_tabViewAction = new QAction(QIcon(":/tabview.png"),
×
198
                                    tr("Switch between tab view and all channels view"), this);
×
199
    m_blindAction = new QAction(QIcon(":/blind.png"),
×
200
                                tr("Toggle blind mode"), this);
×
201
    m_speedDialAction = new QAction(QIcon(":/speed.png"),
×
202
                                    tr("Show/Hide speed dial window"), this);
×
203
    m_recordAction = new QAction(QIcon(":/record.png"),
×
204
                                 tr("Clone this scene and append as a new step to the selected chaser"), this);
×
205

206
    m_nextTabAction = new QAction(QIcon(":/forward.png"), tr("Go to next fixture tab"), this);
×
207
    m_nextTabAction->setShortcut(QKeySequence("Alt+Right"));
×
208
    connect(m_nextTabAction, SIGNAL(triggered(bool)),
×
209
            this, SLOT(slotGoToNextTab()));
210
    m_prevTabAction = new QAction(QIcon(":/back.png"), tr("Go to previous fixture tab"), this);
×
211
    m_prevTabAction->setShortcut(QKeySequence("Alt+Left"));
×
212
    connect(m_prevTabAction, SIGNAL(triggered(bool)),
×
213
            this, SLOT(slotGoToPreviousTab()));
214

215
    // Speed Dial initial state
216
    m_speedDialAction->setCheckable(true);
×
217

218
    // Blind initial state
219
    m_blindAction->setCheckable(true);
×
220

221
    m_tabViewAction->setCheckable(true);
×
222
    if (tabMode.isNull() || tabMode.toInt() == UI_STATE_TABBED_FIXTURES)
×
223
        m_tabViewAction->setChecked(true);
×
224

225
    // Chaser combo init
226
    quint32 selectId = Function::invalidId();
×
227
    QSettings settings;
×
228
    QVariant var = settings.value(SETTINGS_CHASER);
×
229
    if (var.isValid() == true)
×
230
        selectId = var.toUInt();
×
231
    m_chaserCombo = new QComboBox(this);
×
232
    m_chaserCombo->setMaximumWidth(250);
×
233
    m_chaserCombo->addItem(tr("None"), Function::invalidId());
×
234
    slotChaserComboActivated(0);
×
235
    foreach (Function *function, m_doc->functionsByType(Function::ChaserType))
×
236
    {
237
        m_chaserCombo->addItem(function->name(), function->id());
×
238
        if (function->id() == selectId)
×
239
        {
240
            int index = m_chaserCombo->count() - 1;
×
241
            m_chaserCombo->setCurrentIndex(index);
×
242
            slotChaserComboActivated(index);
×
243
        }
244
    }
245
    QLabel *nameLabel = new QLabel(tr("Scene name:"));
×
246
    m_nameEdit = new QLineEdit();
×
247

248
    // Connections
249
    connect(m_enableCurrentAction, SIGNAL(triggered(bool)),
×
250
            this, SLOT(slotEnableCurrent()));
251
    connect(m_disableCurrentAction, SIGNAL(triggered(bool)),
×
252
            this, SLOT(slotDisableCurrent()));
253
    connect(m_copyAction, SIGNAL(triggered(bool)),
×
254
            this, SLOT(slotCopy()));
255
    connect(m_pasteAction, SIGNAL(triggered(bool)),
×
256
            this, SLOT(slotPaste()));
257
    connect(m_copyToAllAction, SIGNAL(triggered(bool)),
×
258
            this, SLOT(slotCopyToAll()));
259
    connect(m_colorToolAction, SIGNAL(triggered(bool)),
×
260
            this, SLOT(slotColorTool()));
261
    connect(m_positionToolAction, SIGNAL(triggered(bool)),
×
262
            this, SLOT(slotPositionTool()));
263
    connect(m_speedDialAction, SIGNAL(toggled(bool)),
×
264
            this, SLOT(slotSpeedDialToggle(bool)));
265
    connect(m_tabViewAction, SIGNAL(toggled(bool)),
×
266
            this, SLOT(slotViewModeChanged(bool)));
267
    connect(m_blindAction, SIGNAL(toggled(bool)),
×
268
            this, SLOT(slotBlindToggled(bool)));
269
    connect(m_recordAction, SIGNAL(triggered(bool)),
×
270
            this, SLOT(slotRecord()));
271
    connect(m_chaserCombo, SIGNAL(activated(int)),
×
272
            this, SLOT(slotChaserComboActivated(int)));
273
    connect(m_doc, SIGNAL(modeChanged(Doc::Mode)),
×
274
            this, SLOT(slotModeChanged(Doc::Mode)));
275

276
    /* Toolbar */
277
    QToolBar* toolBar = new QToolBar(this);
×
278
    layout()->setMenuBar(toolBar);
×
279
    toolBar->addAction(m_enableCurrentAction);
×
280
    toolBar->addAction(m_disableCurrentAction);
×
281
    toolBar->addSeparator();
×
282
    toolBar->addAction(m_prevTabAction);
×
283
    toolBar->addAction(m_nextTabAction);
×
284
    toolBar->addSeparator();
×
285
    toolBar->addAction(m_copyAction);
×
286
    toolBar->addAction(m_pasteAction);
×
287
    toolBar->addAction(m_copyToAllAction);
×
288
    toolBar->addSeparator();
×
289
    toolBar->addAction(m_colorToolAction);
×
290
    toolBar->addAction(m_positionToolAction);
×
291
    toolBar->addSeparator();
×
292
    toolBar->addAction(m_speedDialAction);
×
293
    toolBar->addAction(m_tabViewAction);
×
294
    toolBar->addSeparator();
×
295
    toolBar->addAction(m_blindAction);
×
296
    toolBar->addSeparator();
×
297
    toolBar->addAction(m_recordAction);
×
298
    toolBar->addWidget(m_chaserCombo);
×
299
    toolBar->addSeparator();
×
300
    toolBar->addWidget(nameLabel);
×
301
    toolBar->addWidget(m_nameEdit);
×
302

303
    /* Tab widget */
304
    connect(m_tab, SIGNAL(currentChanged(int)),
×
305
            this, SLOT(slotTabChanged(int)));
306

307
    /* Add & remove buttons */
308
    connect(m_addFixtureButton, SIGNAL(clicked()),
×
309
            this, SLOT(slotAddFixtureClicked()));
310
    connect(m_removeFixtureButton, SIGNAL(clicked()),
×
311
            this, SLOT(slotRemoveFixtureClicked()));
312

313
    m_nameEdit->setText(m_scene->name());
×
314
    m_nameEdit->setSelection(0, m_nameEdit->text().length());
×
315
    connect(m_nameEdit, SIGNAL(textEdited(const QString&)),
×
316
            this, SLOT(slotNameEdited(const QString&)));
317

318
    // Channels groups tab
319
    QList<quint32> chGrpIds = m_scene->channelGroups();
×
320
    QListIterator <ChannelsGroup*> scg(m_doc->channelsGroups());
×
321
    while (scg.hasNext() == true)
×
322
    {
323
        QTreeWidgetItem* item = new QTreeWidgetItem(m_channelGroupsTree);
×
324
        ChannelsGroup *grp = scg.next();
×
325
        item->setText(KColumnName, grp->name());
×
326
        item->setData(KColumnName, Qt::UserRole, grp->id());
×
327

328
        item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
×
329
        if (chGrpIds.contains(grp->id()))
×
330
            item->setCheckState(KColumnName, Qt::Checked);
×
331
        else
332
            item->setCheckState(KColumnName, Qt::Unchecked);
×
333
    }
334
    connect(m_channelGroupsTree, SIGNAL(itemChanged(QTreeWidgetItem*,int)),
×
335
            this, SLOT(slotChannelGroupsChanged(QTreeWidgetItem*,int)));
336
    connect(m_enableChannelsButton, SIGNAL(clicked()),
×
337
            this, SLOT(slotEnableAll()));
338
    connect(m_disableChannelsButton, SIGNAL(clicked()),
×
339
            this, SLOT(slotDisableAll()));
340
    connect(m_selectAllGroups, SIGNAL(clicked()),
×
341
            this, SLOT(slotEnableAllChannelGroups()));
342
    connect(m_deselectAllGroups, SIGNAL(clicked()),
×
343
            this, SLOT(slotDisableAllChannelGroups()));
344
    updateChannelsGroupsTab();
×
345

346
    // Apply any mode related change
347
    slotModeChanged(m_doc->mode());
×
348

349
    // Fixtures & tabs
350
    // Fill the fixtures list from the Scene fixtures
351
    foreach (quint32 fixtureID, m_scene->fixtures())
×
352
    {
353
        if (fixtureItem(fixtureID) == NULL)
×
354
        {
355
            Fixture* fixture = m_doc->fixture(fixtureID);
×
356
            if (fixture == NULL)
×
357
                continue;
×
358
            addFixtureItem(fixture);
×
359
        }
360
    }
361

362
    // Complete the fixtures list from the Scene values
363
    // (This should be useless)
364
    QListIterator <SceneValue> it(m_scene->values());
×
365
    while (it.hasNext() == true)
×
366
    {
367
        SceneValue scv(it.next());
×
368

369
        if (fixtureItem(scv.fxi) == NULL)
×
370
        {
371
            qWarning() << Q_FUNC_INFO
×
372
                << "Fixture" << scv.fxi << "was not in the scene fixture list!";
×
373
            Fixture* fixture = m_doc->fixture(scv.fxi);
×
374
            if (fixture == NULL)
×
375
                continue;
376

377
            addFixtureItem(fixture);
×
378
        }
379
    }
×
380

381
    // Create the actual tab view
382
    if (tabMode.isNull() || tabMode.toInt() == UI_STATE_TABBED_FIXTURES)
×
383
        slotViewModeChanged(true, applyValues);
×
384
    else
385
        slotViewModeChanged(false, applyValues);
×
386
}
×
387

388
void SceneEditor::setSceneValue(const SceneValue& scv)
×
389
{
390
    FixtureConsole* fc;
391
    Fixture* fixture;
392

393
    fixture = m_doc->fixture(scv.fxi);
×
394
    Q_ASSERT(fixture != NULL);
395

396
    fc = fixtureConsole(fixture);
×
397
    if (fc != NULL)
×
398
        fc->setSceneValue(scv);
×
399
}
×
400

401

402
void SceneEditor::setBlindModeEnabled(bool active)
×
403
{
404
    m_blindAction->setChecked(active);
×
405
}
×
406

407
/*****************************************************************************
408
 * Common
409
 *****************************************************************************/
410

411
void SceneEditor::slotTabChanged(int tab)
×
412
{
413
    m_currentTab = tab;
×
414
    QLCClipboard *clipboard = m_doc->clipboard();
×
415

416
    m_scene->setUiStateValue(UI_STATE_TAB_INDEX, tab);
×
417

418
    if (tab == KTabGeneral)
×
419
    {
420
        m_enableCurrentAction->setEnabled(false);
×
421
        m_disableCurrentAction->setEnabled(false);
×
422

423
        m_copyAction->setEnabled(false);
×
424
        m_pasteAction->setEnabled(false);
×
425
        m_copyToAllAction->setEnabled(false);
×
426
        m_colorToolAction->setEnabled(false);
×
427
    }
428
    else
429
    {
430
        m_enableCurrentAction->setEnabled(true);
×
431
        m_disableCurrentAction->setEnabled(true);
×
432

433
        m_copyAction->setEnabled(true);
×
434
        if (clipboard->hasSceneValues())
×
435
            m_pasteAction->setEnabled(true);
×
436
        else
437
            m_pasteAction->setEnabled(false);
×
438

439
        if (m_tabViewAction->isChecked())
×
440
            m_copyToAllAction->setEnabled(true);
×
441
        else
442
            m_copyToAllAction->setEnabled(false);
×
443
        m_colorToolAction->setEnabled(isColorToolAvailable());
×
444
        m_positionToolAction->setEnabled(isPositionToolAvailable());
×
445
    }
446
}
×
447

448
void SceneEditor::slotEnableCurrent()
×
449
{
450
    if (m_tabViewAction->isChecked())
×
451
    {
452
        /* QObject cast fails unless the widget is a FixtureConsole */
453
        FixtureConsole* fc = fixtureConsoleTab(m_currentTab);
×
454
        if (fc != NULL)
×
455
            fc->setChecked(true);
×
456
    }
457
    else
458
    {
NEW
459
        foreach (FixtureConsole *fc, m_consoleList)
×
460
        {
461
            if (fc == NULL)
×
462
                continue;
×
463
            fc->setChecked(true);
×
464
        }
465
    }
466
}
×
467

468
void SceneEditor::slotDisableCurrent()
×
469
{
470
    if (m_tabViewAction->isChecked())
×
471
    {
472
        /* QObject cast fails unless the widget is a FixtureConsole */
473
        FixtureConsole* fc = fixtureConsoleTab(m_currentTab);
×
474
        if (fc != NULL)
×
475
            fc->setChecked(false);
×
476
    }
477
    else
478
    {
NEW
479
        foreach (FixtureConsole *fc, m_consoleList)
×
480
        {
481
            if (fc == NULL)
×
482
                continue;
×
483
            fc->setChecked(false);
×
484
        }
485
    }
486
}
×
487

488
void SceneEditor::slotCopy()
×
489
{
490
    QList <SceneValue> copyList;
491
    QLCClipboard *clipboard = m_doc->clipboard();
×
492

493
    /* QObject cast fails unless the widget is a FixtureConsole */
494
    if (m_tabViewAction->isChecked())
×
495
    {
496
        FixtureConsole* fc = fixtureConsoleTab(m_currentTab);
×
497
        if (fc != NULL)
×
498
        {
499
            copyList = fc->values();
×
NEW
500
            m_copyFromSelection = fc->hasSelections();
×
501
            clipboard->copyContent(m_scene->id(), copyList);
×
502
        }
503
    }
504
    else
505
    {
506
        bool oneHasSelection = false;
507
        QList <SceneValue> selectedOnlyList;
NEW
508
        foreach (FixtureConsole *fc, m_consoleList)
×
509
        {
510
            if (fc == NULL)
×
511
                continue;
×
512
            copyList.append(fc->values());
×
513
            if (fc->hasSelections())
×
514
            {
515
                oneHasSelection = true;
516
                selectedOnlyList.append(fc->values());
×
517
            }
518
        }
519
        m_copyFromSelection = oneHasSelection;
×
520
        if (m_copyFromSelection == true)
×
521
            clipboard->copyContent(m_scene->id(), selectedOnlyList);
×
522
        else
523
            clipboard->copyContent(m_scene->id(), copyList);
×
524
    }
×
525
    if (copyList.count() > 0)
×
526
        m_pasteAction->setEnabled(true);
×
527
}
×
528

529
void SceneEditor::slotPaste()
×
530
{
531
    QLCClipboard *clipboard = m_doc->clipboard();
×
532

533
    if (clipboard->hasSceneValues() == false)
×
534
        return;
535

536
    if (m_tabViewAction->isChecked())
×
537
    {
538
        FixtureConsole* fc = fixtureConsoleTab(m_currentTab);
×
539
        if (fc != NULL)
×
540
            fc->setValues(clipboard->getSceneValues(), m_copyFromSelection);
×
541
    }
542
    else
543
    {
NEW
544
        foreach (FixtureConsole *fc, m_consoleList)
×
545
        {
546
            if (fc == NULL)
×
547
                continue;
×
548
            quint32 fxi = fc->fixture();
×
549
            QList<SceneValue>thisFixtureVals;
550
            foreach (SceneValue val, clipboard->getSceneValues())
×
551
            {
552
                if (val.fxi == fxi)
×
553
                    thisFixtureVals.append(val);
×
554
            }
×
555
            fc->setValues(thisFixtureVals, m_copyFromSelection);
×
556
        }
×
557
    }
558
}
559

560
void SceneEditor::slotCopyToAll()
×
561
{
562
    slotCopy();
×
563

564
    QLCClipboard *clipboard = m_doc->clipboard();
×
565

566
    if (clipboard->hasSceneValues())
×
567
    {
568
        for (int i = m_fixtureFirstTabIndex; i < m_tab->count(); i++)
×
569
        {
570
            FixtureConsole* fc = fixtureConsoleTab(i);
×
571
            if (fc != NULL)
×
572
                fc->setValues(clipboard->getSceneValues(), m_copyFromSelection);
×
573
        }
574
    }
575

576
    //m_copy.clear();
577
    m_pasteAction->setEnabled(false);
×
578
}
×
579

580
void SceneEditor::slotColorTool()
×
581
{
582
    QColor color = slotColorSelectorChanged(QColor());
×
583

584
    QColorDialog dialog(color, this);
×
585
    connect(&dialog, SIGNAL(currentColorChanged(const QColor&)),
×
586
            this, SLOT(slotColorSelectorChanged(const QColor&)));
587

588
    int result = dialog.exec();
×
589
    if (result == QDialog::Rejected)
×
590
    {
591
        slotColorSelectorChanged(color); // reset color to what it previously was
×
592
    }
593
}
×
594

595
void SceneEditor::slotPositionTool()
×
596
{
597
    FixtureConsole* fc = fixtureConsoleTab(m_currentTab);
×
598
    if (fc != NULL)
×
599
    {
600
        QList<SceneValue> origValues = fc->values();
×
601

602
        Fixture* fxi = m_doc->fixture(fc->fixture());
×
603
        QPointF pos;
×
604
        QRectF range;
×
605
        bool panFound = false;
606
        bool tiltFound = false;
607

608
        Q_ASSERT(fxi != NULL);
609

610
        for (int i = 0; i < fxi->heads(); ++i)
×
611
        {
612
             if (!range.isValid())
613
                 range = fxi->degreesRange(i);
×
614

615
             quint32 panMsbChannel = fxi->channelNumber(QLCChannel::Pan, QLCChannel::MSB, i);
×
616
             quint32 panLsbChannel = fxi->channelNumber(QLCChannel::Pan, QLCChannel::LSB, i);
×
617
             quint32 tiltMsbChannel = fxi->channelNumber(QLCChannel::Tilt, QLCChannel::MSB, i);
×
618
             quint32 tiltLsbChannel = fxi->channelNumber(QLCChannel::Tilt, QLCChannel::LSB, i);
×
619

620
             if (panMsbChannel != QLCChannel::invalid())
×
621
             {
622
                 if (!panFound)
×
623
                 {
624
                     qDebug() << "panFound" << i;
625
                     panFound = true;
626
                     qreal v = qreal(fc->value(panMsbChannel));
×
627
                     if (panLsbChannel != QLCChannel::invalid())
×
628
                     {
629
                        v += qreal(fc->value(panLsbChannel)) / qreal(256);
×
630
                     }
631

632
                     pos.setX(v);
633
                 }
634
             }
635

636
             if (tiltMsbChannel != QLCChannel::invalid())
×
637
             {
638
                 if (!tiltFound)
×
639
                 {
640
                     tiltFound = true;
641
                     qDebug() << "tiltFound" << i;
642
                     qreal v = qreal(fc->value(tiltMsbChannel));
×
643
                     if (tiltLsbChannel != QLCChannel::invalid())
×
644
                     {
645
                        v += qreal(fc->value(tiltLsbChannel)) / qreal(256);
×
646
                     }
647

648
                     pos.setY(v);
649
                 }
650
             }
651
        }
652

653
        PositionTool dialog(pos, range);
×
654
        connect(&dialog, SIGNAL(currentPositionChanged(const QPointF&)),
×
655
            this, SLOT(slotPositionSelectorChanged(const QPointF&)));
656

657
        int result = dialog.exec();
×
658
        if (result == QDialog::Rejected)
×
659
        {
660
            fc->setValues(origValues, false); // reset position to what it previously was
×
661
        }
662
    }
×
663
}
×
664

665
QColor SceneEditor::slotColorSelectorChanged(const QColor& color)
×
666
{
667
    QColor returnColor = QColor();
×
668

669
    /* QObject cast fails unless the widget is a FixtureConsole */
670
    FixtureConsole* fc = fixtureConsoleTab(m_currentTab);
×
671
    if (fc != NULL)
×
672
    {
673
        Fixture* fxi = m_doc->fixture(fc->fixture());
×
674
        Q_ASSERT(fxi != NULL);
675

676
        QSet <quint32> cyan    = fxi->channels(QLCChannel::Intensity, QLCChannel::Cyan);
×
677
        QSet <quint32> magenta = fxi->channels(QLCChannel::Intensity, QLCChannel::Magenta);
×
678
        QSet <quint32> yellow  = fxi->channels(QLCChannel::Intensity, QLCChannel::Yellow);
×
679
        QSet <quint32> red     = fxi->channels(QLCChannel::Intensity, QLCChannel::Red);
×
680
        QSet <quint32> green   = fxi->channels(QLCChannel::Intensity, QLCChannel::Green);
×
681
        QSet <quint32> blue    = fxi->channels(QLCChannel::Intensity, QLCChannel::Blue);
×
682

683
        if (!cyan.isEmpty() && !magenta.isEmpty() && !yellow.isEmpty())
×
684
        {
685
            returnColor.setCmyk(fc->value(*cyan.begin()),
×
686
                                fc->value(*magenta.begin()),
×
687
                                fc->value(*yellow.begin()),
×
688
                                0);
689
            if (color.isValid() == true)
×
690
            {
691
                foreach (quint32 ch, cyan)
×
692
                {
693
                    fc->setChecked(true, ch);
×
694
                    fc->setValue(ch, color.cyan());
×
695
                }
696

697
                foreach (quint32 ch, magenta)
×
698
                {
699
                    fc->setChecked(true, ch);
×
700
                    fc->setValue(ch, color.magenta());
×
701
                }
702

703
                foreach (quint32 ch, yellow)
×
704
                {
705
                    fc->setChecked(true, ch);
×
706
                    fc->setValue(ch, color.yellow());
×
707
                }
708
            }
709
        }
710
        else if (!red.isEmpty() && !green.isEmpty() && !blue.isEmpty())
×
711
        {
712
            returnColor.setRgb(fc->value(*red.begin()),
×
713
                               fc->value(*green.begin()),
×
714
                               fc->value(*blue.begin()),
×
715
                               0);
716

717
            if (color.isValid() == true)
×
718
            {
719
                foreach (quint32 ch, red)
×
720
                {
721
                    fc->setChecked(true, ch);
×
722
                    fc->setValue(ch, color.red());
×
723
                }
724

725
                foreach (quint32 ch, green)
×
726
                {
727
                    fc->setChecked(true, ch);
×
728
                    fc->setValue(ch, color.green());
×
729
                }
730

731
                foreach (quint32 ch, blue)
×
732
                {
733
                    fc->setChecked(true, ch);
×
734
                    fc->setValue(ch, color.blue());
×
735
                }
736
            }
737
        }
738
        return returnColor;
739
    }
740

741
    /* QObject cast fails unless the widget is a GroupsConsole */
742
    GroupsConsole* gc = groupConsoleTab(m_currentTab);
×
743
    if (gc != NULL)
×
744
    {
745
        foreach (ConsoleChannel *cc, gc->groups())
×
746
        {
747
            Fixture* fxi = m_doc->fixture(cc->fixture());
×
748
            Q_ASSERT(fxi != NULL);
749
            const QLCChannel *ch = fxi->channel(cc->channelIndex());
×
750
            if (ch->group() == QLCChannel::Intensity)
×
751
            {
752
                if (ch->colour() == QLCChannel::Red)
×
753
                    cc->setValue(color.red());
×
754
                else if (ch->colour() == QLCChannel::Green)
×
755
                    cc->setValue(color.green());
×
756
                else if (ch->colour() == QLCChannel::Blue)
×
757
                    cc->setValue(color.blue());
×
758
                else if (ch->colour() == QLCChannel::Magenta)
×
759
                    cc->setValue(color.magenta());
×
760
                else if (ch->colour() == QLCChannel::Yellow)
×
761
                    cc->setValue(color.yellow());
×
762
                else if (ch->colour() == QLCChannel::Cyan)
×
763
                    cc->setValue(color.cyan());
×
764
            }
765
        }
766
    }
767

768
    return returnColor;
769
}
770

771
void SceneEditor::slotPositionSelectorChanged(const QPointF& position)
×
772
{
773
    qreal x = position.x();
774
    qreal y = position.y();
775

776
    uchar panMsbNew = x;
×
777
    uchar panLsbNew = (x - floor(x)) * 256;
×
778
    uchar tiltMsbNew = y;
×
779
    uchar tiltLsbNew = (y - floor(y)) * 256;
×
780

781
    /* QObject cast fails unless the widget is a FixtureConsole */
782
    FixtureConsole* fc = fixtureConsoleTab(m_currentTab);
×
783
    if (fc != NULL)
×
784
    {
785
        Fixture* fxi = m_doc->fixture(fc->fixture());
×
786
        Q_ASSERT(fxi != NULL);
787

788
        for (int i = 0; i < fxi->heads(); ++i)
×
789
        {
790
             quint32 panMsbChannel = fxi->channelNumber(QLCChannel::Pan, QLCChannel::MSB, i);
×
791
             quint32 panLsbChannel = fxi->channelNumber(QLCChannel::Pan, QLCChannel::LSB, i);
×
792
             quint32 tiltMsbChannel = fxi->channelNumber(QLCChannel::Tilt, QLCChannel::MSB, i);
×
793
             quint32 tiltLsbChannel = fxi->channelNumber(QLCChannel::Tilt, QLCChannel::LSB, i);
×
794

795
             if (panMsbChannel != QLCChannel::invalid())
×
796
             {
797
                 fc->setChecked(true, panMsbChannel);
×
798
                 fc->setValue(panMsbChannel, panMsbNew);
×
799

800
                 if (panLsbChannel != QLCChannel::invalid())
×
801
                 {
802
                     fc->setChecked(true, panLsbChannel);
×
803
                     fc->setValue(panLsbChannel, panLsbNew);
×
804
                 }
805
             }
806

807
             if (tiltMsbChannel != QLCChannel::invalid())
×
808
             {
809
                 fc->setChecked(true, tiltMsbChannel);
×
810
                 fc->setValue(tiltMsbChannel, tiltMsbNew);
×
811

812
                 if (tiltLsbChannel != QLCChannel::invalid())
×
813
                 {
814
                     fc->setChecked(true, tiltLsbChannel);
×
815
                     fc->setValue(tiltLsbChannel, tiltLsbNew);
×
816
                 }
817
             }
818
        }
819
    }
820

821
    /* QObject cast fails unless the widget is a GroupsConsole */
822
    GroupsConsole* gc = groupConsoleTab(m_currentTab);
×
823
    if (gc != NULL)
×
824
    {
825
        foreach (ConsoleChannel *cc, gc->groups())
×
826
        {
827
            Fixture* fxi = m_doc->fixture(cc->fixture());
×
828
            Q_ASSERT(fxi != NULL);
829
            const QLCChannel *ch = fxi->channel(cc->channelIndex());
×
830
            if (ch->group() == QLCChannel::Pan)
×
831
            {
832
                if (ch->controlByte() == QLCChannel::MSB)
×
833
                    cc->setValue(panMsbNew);
×
834
                else
835
                    cc->setValue(panLsbNew);
×
836
            }
837
            else if (ch->group() == QLCChannel::Tilt)
×
838
            {
839
                if (ch->controlByte() == QLCChannel::MSB)
×
840
                    cc->setValue(tiltMsbNew);
×
841
                else
842
                    cc->setValue(tiltLsbNew);
×
843
            }
844
        }
845
    }
846
}
×
847

848
void SceneEditor::slotSpeedDialToggle(bool state)
×
849
{
850
    if (state == true)
×
851
    {
852
        createSpeedDials();
×
853
    }
854
    else
855
    {
856
        if (m_speedDials != NULL)
×
857
            m_speedDials->deleteLater();
×
858
        m_speedDials = NULL;
×
859
    }
860

861
    m_scene->setUiStateValue(UI_STATE_SHOW_DIAL, state);
×
862
}
×
863

864
void SceneEditor::slotBlindToggled(bool state)
×
865
{
866
    if (m_doc->mode() == Doc::Operate)
×
867
    {
868
        delete m_source;
×
869
        m_source = NULL;
×
870

871
        if (m_scene != NULL && !m_scene->isRunning())
×
872
        {
873
            m_source = new GenericDMXSource(m_doc);
×
874
            foreach (SceneValue scv, m_scene->values())
×
875
                m_source->set(scv.fxi, scv.channel, scv.value);
×
876
        }
877
    }
878
    else
879
    {
880
        if (m_source == NULL)
×
881
            m_source = new GenericDMXSource(m_doc);
×
882
    }
883

884
    if (m_source != NULL)
×
885
        m_source->setOutputEnabled(!state);
×
886
}
×
887

888
void SceneEditor::slotModeChanged(Doc::Mode mode)
×
889
{
890
    if (mode == Doc::Operate)
×
891
    {
892
        m_blindAction->setChecked(true);
×
893
        slotBlindToggled(true);
×
894
    }
895
    else
896
    {
897
        m_blindAction->setChecked(false);
×
898
        slotBlindToggled(false);
×
899
    }
900

901
}
×
902

903
void SceneEditor::slotViewModeChanged(bool tabbed, bool applyValues)
×
904
{
905
    m_tab->blockSignals(true);
×
906
    for (int i = m_tab->count() - 1; i >= m_fixtureFirstTabIndex; i--)
×
907
    {
908
        QScrollArea* area = qobject_cast<QScrollArea*> (m_tab->widget(i));
×
909
        Q_ASSERT(area != NULL);
910
        m_tab->removeTab(i);
×
911
        delete area; // Deletes also FixtureConsole
×
912
    }
913
    m_consoleList.clear();
×
914
    m_tab->blockSignals(false);
×
915

916
    // all fixtures view mode
917
    if (tabbed == false)
×
918
    {
919
        QListIterator <Fixture*> it(selectedFixtures());
×
920
        if (it.hasNext() == true)
×
921
        {
922
            QScrollArea* scrollArea = new QScrollArea(m_tab);
×
923

924
            scrollArea->setWidgetResizable(true);
×
925
            int tIdx = m_tab->addTab(scrollArea, tr("All fixtures"));
×
926
            m_tab->setTabToolTip(tIdx, tr("All fixtures"));
×
927

928
            QGroupBox* grpBox = new QGroupBox(scrollArea);
×
929
            grpBox->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
×
930
            QHBoxLayout* fixturesLayout = new QHBoxLayout(grpBox);
×
931
            grpBox->setLayout(fixturesLayout);
×
932
            fixturesLayout->setSpacing(2);
×
933
            fixturesLayout->setContentsMargins(0, 2, 2, 2);
×
934

935
            int c = 0;
936
            while (it.hasNext() == true)
×
937
            {
938
                Fixture* fixture = it.next();
×
939
                Q_ASSERT(fixture != NULL);
940
                FixtureConsole* console = NULL;
941
                if (c%2 == 0)
×
942
                    console = new FixtureConsole(scrollArea, m_doc, FixtureConsole::GroupOdd);
×
943
                else
944
                    console = new FixtureConsole(scrollArea, m_doc, FixtureConsole::GroupEven);
×
945
                console->setFixture(fixture->id());
×
946
                console->setChecked(false);
×
947
                m_consoleList[fixture->id()] = console;
×
948

949
                connect(console, SIGNAL(valueChanged(quint32,quint32,uchar)),
×
950
                        this, SLOT(slotValueChanged(quint32,quint32,uchar)));
951
                connect(console, SIGNAL(checked(quint32,quint32,bool)),
×
952
                        this, SLOT(slotChecked(quint32,quint32,bool)));
953

954
                QListIterator <SceneValue> it(m_scene->values());
×
955
                while (it.hasNext() == true)
×
956
                {
957
                    SceneValue scv(it.next());
×
958
                    if (applyValues == false)
×
959
                        scv.value = 0;
×
960
                    if (scv.fxi == fixture->id())
×
961
                        console->setSceneValue(scv);
×
962
                }
×
963

964
                fixturesLayout->addWidget(console);
×
965
                c++;
×
966
            }
967
            fixturesLayout->addStretch(1);
×
968
            scrollArea->setWidget(grpBox);
×
969
        }
970
    }
971
    // tabbed fixtures view mode
972
    else
973
    {
974
        QListIterator <Fixture*> it(selectedFixtures());
×
975
        while (it.hasNext() == true)
×
976
        {
977
            Fixture* fixture = it.next();
×
978
            Q_ASSERT(fixture != NULL);
979

980
            addFixtureTab(fixture);
×
981

982
            QListIterator <SceneValue> it(m_scene->values());
×
983
            while (it.hasNext() == true)
×
984
            {
985
                SceneValue scv(it.next());
×
986
                if (applyValues == false)
×
987
                    scv.value = 0;
×
988
                if (scv.fxi == fixture->id())
×
989
                    setSceneValue(scv);
×
990
            }
×
991
        }
992
    }
993

994
    m_scene->setUiStateValue(UI_STATE_TAB_MODE, tabbed ? UI_STATE_TABBED_FIXTURES : UI_STATE_ALL_FIXTURES);
×
995

996
    if (m_tab->count() == 0)
×
997
    {
998
        slotTabChanged(KTabGeneral);
×
999
    }
1000
    else
1001
    {
1002
        QVariant tabIndex = m_scene->uiStateValue(UI_STATE_TAB_INDEX);
×
1003
        int prevTabIdx = tabIndex.isValid() ? tabIndex.toInt() : 0;
×
1004
        if (prevTabIdx > m_tab->count())
×
1005
            m_tab->setCurrentIndex(m_fixtureFirstTabIndex);
×
1006
        else
1007
            m_tab->setCurrentIndex(prevTabIdx);
×
1008
    }
×
1009

1010
    m_scene->setUiStateValue(UI_STATE_TAB_INDEX, m_tab->currentIndex());
×
1011
}
×
1012

1013
void SceneEditor::slotRecord()
×
1014
{
1015
    Chaser* chaser = selectedChaser();
×
1016
    if (chaser == NULL)
×
1017
        return;
×
1018

1019
    QString name = chaser->name() + QString(" - %1").arg(chaser->steps().size() + 1);
×
1020
    Scene* clone = new Scene(m_doc);
×
1021
    clone->copyFrom(m_scene);
×
1022
    clone->setName(name);
×
1023
    m_doc->addFunction(clone);
×
1024
    chaser->addStep(ChaserStep(clone->id()));
×
1025

1026
    // Switch to the cloned scene
1027
    FunctionManager::instance()->selectFunction(clone->id());
×
1028
}
×
1029

1030
void SceneEditor::slotChaserComboActivated(int index)
×
1031
{
1032
    quint32 id = m_chaserCombo->itemData(index).toUInt();
×
1033
    if (id == Function::invalidId())
×
1034
        m_recordAction->setEnabled(false);
×
1035
    else
1036
        m_recordAction->setEnabled(true);
×
1037
}
×
1038

1039
bool SceneEditor::isColorToolAvailable()
×
1040
{
1041
    Fixture* fxi = NULL;
1042
    quint32 cyan = QLCChannel::invalid(), magenta = QLCChannel::invalid(), yellow = QLCChannel::invalid();
×
1043
    quint32 red = QLCChannel::invalid(), green = QLCChannel::invalid(), blue = QLCChannel::invalid();
×
1044

1045
    /* QObject cast fails unless the widget is a FixtureConsole */
1046
    FixtureConsole* fc = fixtureConsoleTab(m_currentTab);
×
1047
    if (fc != NULL)
×
1048
    {
1049
        fxi = m_doc->fixture(fc->fixture());
×
1050
        Q_ASSERT(fxi != NULL);
1051

1052
        cyan = fxi->channel(QLCChannel::Intensity, QLCChannel::Cyan);
×
1053
        magenta = fxi->channel(QLCChannel::Intensity, QLCChannel::Magenta);
×
1054
        yellow = fxi->channel(QLCChannel::Intensity, QLCChannel::Yellow);
×
1055
        red = fxi->channel(QLCChannel::Intensity, QLCChannel::Red);
×
1056
        green = fxi->channel(QLCChannel::Intensity, QLCChannel::Green);
×
1057
        blue = fxi->channel(QLCChannel::Intensity, QLCChannel::Blue);
×
1058
    }
1059

1060
    GroupsConsole* gc = groupConsoleTab(m_currentTab);
×
1061
    if (gc != NULL)
×
1062
    {
1063
        cyan = magenta = yellow = red = green = blue = QLCChannel::invalid();
×
1064
        foreach (ConsoleChannel *cc, gc->groups())
×
1065
        {
1066
            fxi = m_doc->fixture(cc->fixture());
×
1067
            Q_ASSERT(fxi != NULL);
1068
            const QLCChannel *ch = fxi->channel(cc->channelIndex());
×
1069
            if (ch->group() == QLCChannel::Intensity)
×
1070
            {
1071
                if (ch->colour() == QLCChannel::Red)
×
1072
                    red = 1;
1073
                else if (ch->colour() == QLCChannel::Green)
×
1074
                    green = 1;
1075
                else if (ch->colour() == QLCChannel::Blue)
×
1076
                    blue = 1;
1077
                else if (ch->colour() == QLCChannel::Magenta)
×
1078
                    magenta = 1;
1079
                else if (ch->colour() == QLCChannel::Yellow)
×
1080
                    yellow = 1;
1081
                else if (ch->colour() == QLCChannel::Cyan)
×
1082
                    cyan = 1;
1083
            }
1084
        }
1085
    }
1086

1087
    if (cyan != QLCChannel::invalid() && magenta != QLCChannel::invalid() &&
×
1088
        yellow != QLCChannel::invalid())
×
1089
    {
1090
        return true;
1091
    }
1092
    else if (red != QLCChannel::invalid() && green != QLCChannel::invalid() &&
×
1093
             blue != QLCChannel::invalid())
×
1094
    {
1095
        return true;
1096
    }
1097
    else
1098
    {
1099
        return false;
×
1100
    }
1101
}
1102

1103
bool SceneEditor::isPositionToolAvailable()
×
1104
{
1105
    Fixture* fxi = NULL;
1106

1107
    /* QObject cast fails unless the widget is a FixtureConsole */
1108
    FixtureConsole* fc = fixtureConsoleTab(m_currentTab);
×
1109
    if (fc != NULL)
×
1110
    {
1111
        fxi = m_doc->fixture(fc->fixture());
×
1112
        Q_ASSERT(fxi != NULL);
1113

1114
        for (int i = 0; i < fxi->heads(); ++i)
×
1115
        {
1116
            if (fxi->channelNumber(QLCChannel::Pan, QLCChannel::MSB, i) != QLCChannel::invalid())
×
1117
                return true;
1118
            if (fxi->channelNumber(QLCChannel::Tilt, QLCChannel::MSB, i) != QLCChannel::invalid())
×
1119
                return true;
1120
        }
1121
    }
1122

1123
    GroupsConsole* gc = groupConsoleTab(m_currentTab);
×
1124
    if (gc != NULL)
×
1125
    {
1126
        foreach (ConsoleChannel *cc, gc->groups())
×
1127
        {
1128
            fxi = m_doc->fixture(cc->fixture());
×
1129
            Q_ASSERT(fxi != NULL);
1130
            const QLCChannel *ch = fxi->channel(cc->channelIndex());
×
1131
            if (ch->group() == QLCChannel::Pan || ch->group() == QLCChannel::Tilt)
×
1132
                return true;
1133
        }
1134
    }
1135

1136
    return false;
1137
}
1138

1139
void SceneEditor::createSpeedDials()
×
1140
{
1141
    if (m_speedDials != NULL)
×
1142
        return;
1143

1144
    m_speedDials = new SpeedDialWidget(this);
×
1145
    m_speedDials->setAttribute(Qt::WA_DeleteOnClose);
×
1146
    m_speedDials->setWindowTitle(m_scene->name());
×
1147
    m_speedDials->setFadeInSpeed(m_scene->fadeInSpeed());
×
1148
    m_speedDials->setFadeOutSpeed(m_scene->fadeOutSpeed());
×
1149
    m_speedDials->setDurationEnabled(false);
×
1150
    m_speedDials->setDurationVisible(false);
×
1151
    connect(m_speedDials, SIGNAL(fadeInChanged(int)), this, SLOT(slotFadeInChanged(int)));
×
1152
    connect(m_speedDials, SIGNAL(fadeOutChanged(int)), this, SLOT(slotFadeOutChanged(int)));
×
1153
    connect(m_speedDials, SIGNAL(destroyed(QObject*)), this, SLOT(slotDialDestroyed(QObject*)));
×
1154
    m_speedDials->show();
×
1155
}
1156

1157
void SceneEditor::slotDialDestroyed(QObject *)
×
1158
{
1159
    m_speedDialAction->setChecked(false);
×
1160
}
×
1161

1162
Chaser* SceneEditor::selectedChaser() const
×
1163
{
1164
    QVariant var = m_chaserCombo->itemData(m_chaserCombo->currentIndex());
×
1165
    if (var.isValid() == false)
×
1166
        return NULL;
1167
    else
1168
        return qobject_cast<Chaser*> (m_doc->function(var.toUInt()));
×
1169
}
×
1170

1171
/*****************************************************************************
1172
 * General page
1173
 *****************************************************************************/
1174

1175
QTreeWidgetItem* SceneEditor::fixtureItem(quint32 fxi_id)
×
1176
{
1177
    QTreeWidgetItemIterator it(m_tree);
×
1178
    while (*it != NULL)
×
1179
    {
1180
        QTreeWidgetItem* item = *it;
1181
        if (item->text(KColumnID).toUInt() == fxi_id)
×
1182
            return item;
×
1183
        ++it;
×
1184
    }
1185

1186
    return NULL;
1187
}
×
1188

1189
QList <Fixture*> SceneEditor::selectedFixtures() const
×
1190
{
1191
    QListIterator <QTreeWidgetItem*> it(m_tree->selectedItems());
×
1192
    QList <Fixture*> list;
1193

1194
    while (it.hasNext() == true)
×
1195
    {
1196
        QTreeWidgetItem* item;
1197
        quint32 fxi_id;
1198
        Fixture* fixture;
1199

1200
        item = it.next();
×
1201
        fxi_id = item->text(KColumnID).toInt();
×
1202
        fixture = m_doc->fixture(fxi_id);
×
1203
        Q_ASSERT(fixture != NULL);
1204

1205
        list.append(fixture);
×
1206
    }
1207

1208
    return list;
×
1209
}
×
1210

1211
bool SceneEditor::addFixtureItem(Fixture* fixture)
×
1212
{
1213
    Q_ASSERT(fixture != NULL);
1214

1215
    // check if the fixture is already there
1216
    for (int i = 0; i < m_tree->topLevelItemCount(); i++)
×
1217
    {
1218
        QTreeWidgetItem *fix = m_tree->topLevelItem(i);
×
1219
        if (fix != NULL)
×
1220
        {
1221
            quint32 fxid = fix->text(KColumnID).toUInt();
×
1222
            if (fxid == fixture->id())
×
1223
                return false;
1224
        }
1225
    }
1226

1227
    QTreeWidgetItem* item;
1228

1229
    item = new QTreeWidgetItem(m_tree);
×
1230
    item->setText(KColumnName, fixture->name());
×
1231
    item->setText(KColumnID, QString("%1").arg(fixture->id()));
×
1232

1233
    if (fixture->fixtureDef() == NULL)
×
1234
    {
1235
        item->setText(KColumnManufacturer, tr("Generic"));
×
1236
        item->setText(KColumnModel, tr("Generic"));
×
1237
    }
1238
    else
1239
    {
1240
        item->setText(KColumnManufacturer,
×
1241
                      fixture->fixtureDef()->manufacturer());
×
1242
        item->setText(KColumnModel, fixture->fixtureDef()->model());
×
1243
    }
1244

1245
    /* Select newly-added fixtures so that their channels can be
1246
       quickly disabled/enabled */
1247
    item->setSelected(true);
×
1248

1249
    return true;
×
1250
}
1251

1252
void SceneEditor::removeFixtureItem(quint32 fixtureID)
×
1253
{
1254
    QTreeWidgetItem *item;
1255

1256
    item = fixtureItem(fixtureID);
×
1257
    delete item;
×
1258
}
×
1259

1260
void SceneEditor::slotNameEdited(const QString& name)
×
1261
{
1262
    m_scene->setName(name);
×
1263
    if (m_speedDials != NULL)
×
1264
        m_speedDials->setWindowTitle(m_scene->name());
×
1265
}
×
1266

1267
void SceneEditor::slotAddFixtureClicked()
×
1268
{
1269
    /* Put all fixtures already present into a list of fixtures that
1270
       will be disabled in the fixture selection dialog */
1271
    QList <quint32> disabled;
1272
    QTreeWidgetItemIterator twit(m_tree);
×
1273
    while (*twit != NULL)
×
1274
    {
1275
        disabled.append((*twit)->text(KColumnID).toInt());
×
1276
        twit++;
×
1277
    }
1278

1279
    /* Get a list of new fixtures to add to the scene */
1280
    FixtureSelection fs(this, m_doc);
×
1281
    fs.setMultiSelection(true);
×
1282
    fs.setDisabledFixtures(disabled);
×
1283
    if (fs.exec() == QDialog::Accepted)
×
1284
    {
1285
        QListIterator <quint32> it(fs.selection());
×
1286
        while (it.hasNext() == true)
×
1287
        {
1288
            Fixture *fixture = m_doc->fixture(it.next());
×
1289
            Q_ASSERT(fixture != NULL);
1290

1291
            addFixtureItem(fixture);
×
1292
            addFixtureTab(fixture);
×
1293

1294
            // Add fixture in scene
1295
            m_scene->addFixture(fixture->id());
×
1296
        }
1297
    }
1298
}
×
1299

1300
void SceneEditor::slotRemoveFixtureClicked()
×
1301
{
1302
    int r = QMessageBox::question(
×
1303
                this, tr("Remove fixtures"),
×
1304
                tr("Do you want to remove the selected fixture(s)?"),
×
1305
                QMessageBox::Yes, QMessageBox::No);
1306

1307
    if (r == QMessageBox::Yes)
×
1308
    {
1309
        QListIterator <Fixture*> it(selectedFixtures());
×
1310
        while (it.hasNext() == true)
×
1311
        {
1312
            Fixture* fixture = it.next();
×
1313
            Q_ASSERT(fixture != NULL);
1314

1315
            removeFixtureTab(fixture->id());
×
1316
            removeFixtureItem(fixture->id());
×
1317

1318
            /* Remove all values associated to the fixture */
1319
            for (quint32 i = 0; i < fixture->channels(); i++)
×
1320
                m_scene->unsetValue(fixture->id(), i);
×
1321

1322
            // Remove fixture from scene
1323
            m_scene->removeFixture(fixture->id());
×
1324
        }
1325
    }
1326
}
×
1327

1328
void SceneEditor::slotEnableAll()
×
1329
{
NEW
1330
    foreach (FixtureConsole* fc, m_consoleList)
×
1331
    {
1332
        if (fc != NULL)
×
1333
            fc->setChecked(true);
×
1334
    }
1335
}
×
1336

1337
void SceneEditor::slotDisableAll()
×
1338
{
NEW
1339
    foreach (FixtureConsole* fc, m_consoleList)
×
1340
    {
1341
        if (fc != NULL)
×
1342
            fc->setChecked(false);
×
1343
    }
1344
}
×
1345

1346
void SceneEditor::slotFadeInChanged(int ms)
×
1347
{
1348
    m_scene->setFadeInSpeed(ms);
×
1349
}
×
1350

1351
void SceneEditor::slotFadeOutChanged(int ms)
×
1352
{
1353
    m_scene->setFadeOutSpeed(ms);
×
1354
}
×
1355

1356
void SceneEditor::slotEnableAllChannelGroups()
×
1357
{
1358
    for (int i = 0; i < m_channelGroupsTree->topLevelItemCount(); i++)
×
1359
    {
1360
        QTreeWidgetItem *item = m_channelGroupsTree->topLevelItem(i);
×
1361
        item->setCheckState(KColumnName, Qt::Checked);
×
1362
    }
1363
}
×
1364

1365
void SceneEditor::slotDisableAllChannelGroups()
×
1366
{
1367
    for (int i = 0; i < m_channelGroupsTree->topLevelItemCount(); i++)
×
1368
    {
1369
        QTreeWidgetItem *item = m_channelGroupsTree->topLevelItem(i);
×
1370
        item->setCheckState(KColumnName, Qt::Unchecked);
×
1371
    }
1372
}
×
1373

1374
void SceneEditor::slotChannelGroupsChanged(QTreeWidgetItem *item, int column)
×
1375
{
1376
    if (item == NULL)
×
1377
        return;
1378

1379
    quint32 grpID = item->data(column, Qt::UserRole).toUInt();
×
1380
    ChannelsGroup *grp = m_doc->channelsGroup(grpID);
×
1381
    if (grp == NULL)
×
1382
        return;
1383

1384
    if (item->checkState(column) == Qt::Checked)
×
1385
    {
1386
        m_scene->addChannelGroup(grpID);
×
1387
        foreach (SceneValue val, grp->getChannels())
×
1388
        {
1389
            Fixture *fixture = m_doc->fixture(val.fxi);
×
1390
            if (fixture != NULL)
×
1391
            {
1392
                if (addFixtureItem(fixture) == true)
×
1393
                    addFixtureTab(fixture, val.channel);
×
1394
                else
1395
                    setTabChannelState(true, fixture, val.channel);
×
1396
            }
1397
        }
×
1398
    }
1399
    else
1400
    {
1401
        m_scene->removeChannelGroup(grpID);
×
1402
        foreach (SceneValue val, grp->getChannels())
×
1403
        {
1404
            Fixture *fixture = m_doc->fixture(val.fxi);
×
1405
            if (fixture != NULL)
×
1406
                setTabChannelState(false, fixture, val.channel);
×
1407
        }
×
1408
    }
1409

1410
    qDebug() << Q_FUNC_INFO << "Groups in list: " << m_scene->channelGroups().count();
1411

1412
    updateChannelsGroupsTab();
×
1413
}
1414

1415
/*********************************************************************
1416
 * Channels groups tabs
1417
 *********************************************************************/
1418
void SceneEditor::updateChannelsGroupsTab()
×
1419
{
1420
    QScrollArea* scrollArea = NULL;
1421
    QList <quint32> ids = m_scene->channelGroups();
×
1422

1423
    if (m_channelGroupsTree->topLevelItemCount() == 0)
×
1424
    {
1425
        m_fixtureFirstTabIndex = 1;
×
1426
        return;
×
1427
    }
1428

1429
    /* Get a scroll area for the console */
1430
    if (m_channelGroupsTab != -1)
×
1431
    {
1432
        scrollArea = qobject_cast<QScrollArea*> (m_tab->widget(m_channelGroupsTab));
×
1433
        Q_ASSERT(scrollArea != NULL);
1434
        GroupsConsole *tmpGrpConsole = qobject_cast<GroupsConsole*> (scrollArea->widget());
×
1435
        Q_ASSERT(tmpGrpConsole != NULL);
1436
        delete tmpGrpConsole;
×
1437
        if (ids.count() == 0)
×
1438
        {
1439
            m_tab->removeTab(1);
×
1440
            m_channelGroupsTab = -1;
×
1441
            m_fixtureFirstTabIndex = 1;
×
1442
            return;
×
1443
        }
1444
    }
1445
    else
1446
    {
1447
        if (ids.count() == 0)
×
1448
            return;
1449
        scrollArea = new QScrollArea(m_tab);
×
1450
    }
1451

1452
    QList<uchar>levels = m_scene->channelGroupsLevels();
×
1453
    GroupsConsole* console = new GroupsConsole(scrollArea, m_doc, ids, levels);
×
1454
    scrollArea->setWidget(console);
×
1455
    scrollArea->setWidgetResizable(true);
×
1456
    if (m_channelGroupsTab == -1)
×
1457
    {
1458
        m_tab->insertTab(1, scrollArea, tr("Channels Groups"));
×
1459
        m_tab->setTabToolTip(1, tr("Channels Groups"));
×
1460
    }
1461

1462
    m_channelGroupsTab = 1;
×
1463
    m_fixtureFirstTabIndex = 2;
×
1464
    connect(console, SIGNAL(groupValueChanged(quint32,uchar)),
×
1465
            this, SLOT(slotGroupValueChanged(quint32,uchar)));
1466
}
×
1467

1468
GroupsConsole *SceneEditor::groupConsoleTab(int tab)
×
1469
{
1470
    if (tab != m_channelGroupsTab)
×
1471
        return NULL;
1472

1473
    QScrollArea* area = qobject_cast<QScrollArea*> (m_tab->widget(tab));
×
1474
    Q_ASSERT(area != NULL);
1475

1476
    return qobject_cast<GroupsConsole*> (area->widget());
×
1477
}
1478

1479
void SceneEditor::slotGroupValueChanged(quint32 groupID, uchar value)
×
1480
{
1481
    // Don't modify m_scene contents when doing initialization
1482
    if (m_initFinished == true)
×
1483
    {
1484
        Q_ASSERT(m_scene != NULL);
1485
        ChannelsGroup *group = m_doc->channelsGroup(groupID);
×
1486
        if (group == NULL)
×
1487
            return;
1488
        foreach (SceneValue scv, group->getChannels())
×
1489
        {
1490
            Fixture *fixture = m_doc->fixture(scv.fxi);
×
1491
            if (fixture == NULL)
×
1492
                continue;
×
1493
            FixtureConsole *fc = fixtureConsole(fixture);
×
1494
            if (fc == NULL)
×
1495
                continue;
×
1496
            fc->setValue(scv.channel, value);
×
1497
        }
×
1498
        m_scene->setChannelGroupLevel(groupID, value);
×
1499
    }
1500
}
1501

1502
/*****************************************************************************
1503
 * Fixture tabs
1504
 *****************************************************************************/
1505

1506
FixtureConsole* SceneEditor::fixtureConsole(Fixture* fixture)
×
1507
{
1508
    Q_ASSERT(fixture != NULL);
1509

1510
    if (m_consoleList.contains(fixture->id()))
×
1511
        return m_consoleList[fixture->id()];
×
1512

1513
    return NULL;
1514
}
1515

1516
void SceneEditor::addFixtureTab(Fixture* fixture, quint32 channel)
×
1517
{
1518
    Q_ASSERT(fixture != NULL);
1519

1520
    /* Put the console inside a scroll area */
1521
    QScrollArea* scrollArea = new QScrollArea(m_tab);
×
1522
    scrollArea->setWidgetResizable(true);
×
1523

1524
    FixtureConsole* console = new FixtureConsole(scrollArea, m_doc);
×
1525
    console->setFixture(fixture->id());
×
1526
    m_consoleList[fixture->id()] = console;
×
1527
    scrollArea->setWidget(console);
×
1528
    int tIdx = m_tab->addTab(scrollArea, fixture->name());
×
1529
    m_tab->setTabToolTip(tIdx, fixture->name());
×
1530

1531
    /* Start off with all channels disabled */
1532
    console->setChecked(false);
×
1533

1534
    connect(console, SIGNAL(valueChanged(quint32,quint32,uchar)),
×
1535
            this, SLOT(slotValueChanged(quint32,quint32,uchar)));
1536
    connect(console, SIGNAL(checked(quint32,quint32,bool)),
×
1537
            this, SLOT(slotChecked(quint32,quint32,bool)));
1538

1539
    if (channel != QLCChannel::invalid())
×
1540
        console->setChecked(true, channel);
×
1541
}
×
1542

1543
void SceneEditor::removeFixtureTab(quint32 fixtureID)
×
1544
{
1545
    /* Start searching from the first fixture tab */
1546
    for (int i = m_fixtureFirstTabIndex; i < m_tab->count(); i++)
×
1547
    {
1548
        FixtureConsole* fc = fixtureConsoleTab(i);
×
1549
        if (fc != NULL && fc->fixture() == fixtureID)
×
1550
        {
1551
            /* First remove the tab because otherwise Qt might
1552
               remove two tabs -- undocumented feature, which
1553
               might be intended or it might not. */
1554
            QScrollArea* area = qobject_cast<QScrollArea*> (m_tab->widget(i));
×
1555
            Q_ASSERT(area != NULL);
1556
            m_tab->removeTab(i);
×
1557
            m_consoleList.take(fixtureID);
×
1558
            delete area; // Deletes also FixtureConsole
×
1559
            break;
1560
        }
1561
    }
1562
}
×
1563

1564
FixtureConsole* SceneEditor::fixtureConsoleTab(int tab)
×
1565
{
1566
    if (tab >= m_tab->count() || tab <= 0)
×
1567
        return NULL;
1568

1569
    QScrollArea* area = qobject_cast<QScrollArea*> (m_tab->widget(tab));
×
1570
    Q_ASSERT(area != NULL);
1571

1572
    return qobject_cast<FixtureConsole*> (area->widget());
×
1573
}
1574

1575
void SceneEditor::setTabChannelState(bool status, Fixture *fixture, quint32 channel)
×
1576
{
1577
    Q_ASSERT(fixture != NULL);
1578

1579
    if (channel == QLCChannel::invalid())
×
1580
        return;
1581

1582
    if (m_consoleList.contains(fixture->id()))
×
1583
        m_consoleList[fixture->id()]->setChecked(status, channel);
×
1584
}
1585

1586
void SceneEditor::slotValueChanged(quint32 fxi, quint32 channel, uchar value)
×
1587
{
1588
    // Don't modify m_scene contents when doing initialization
1589
    if (m_initFinished == true)
×
1590
    {
1591
        Q_ASSERT(m_scene != NULL);
1592

1593
        if (m_doc->mode() == Doc::Operate)
×
1594
            m_scene->setValue(SceneValue(fxi, channel, value), m_blindAction->isChecked(), false);
×
1595
        else
1596
            m_scene->setValue(SceneValue(fxi, channel, value), m_blindAction->isChecked(), true);
×
1597
        emit fixtureValueChanged(SceneValue(fxi, channel, value), true);
×
1598
    }
1599

1600
    if (m_source != NULL)
×
1601
        m_source->set(fxi, channel, value);
×
1602
}
×
1603

1604
void SceneEditor::slotChecked(quint32 fxi, quint32 channel, bool state)
×
1605
{
1606
    // Don't modify m_scene contents when doing initialization
1607
    if (m_initFinished == true)
×
1608
    {
1609
        // When a channel is enabled, its current value is emitted with valueChanged().
1610
        // So, state == true case doesn't need to be handled here.
1611
        Q_ASSERT(m_scene != NULL);
1612
        if (state == false)
×
1613
        {
1614
            m_scene->unsetValue(fxi, channel);
×
1615
            if (m_source != NULL)
×
1616
            {
1617
                m_source->unset(fxi, channel);
×
1618
                emit fixtureValueChanged(SceneValue(fxi, channel, 0), false);
×
1619
            }
1620
        }
1621
    }
1622
}
×
1623

1624
void SceneEditor::slotGoToNextTab()
×
1625
{
1626
    m_currentTab++;
×
1627
    if (m_currentTab == m_tab->count())
×
1628
        m_currentTab = 0;
×
1629
    m_tab->setCurrentIndex(m_currentTab);
×
1630
}
×
1631

1632
void SceneEditor::slotGoToPreviousTab()
×
1633
{
1634
    if (m_currentTab == 0)
×
1635
        m_currentTab = m_tab->count() - 1;
×
1636
    else
1637
        m_currentTab--;
×
1638
    m_tab->setCurrentIndex(m_currentTab);
×
1639
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc