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

mcallegari / qlcplus / 13633248611

03 Mar 2025 02:31PM UTC coverage: 31.871% (+0.4%) from 31.5%
13633248611

push

github

web-flow
actions: add chrpath to profile

14689 of 46089 relevant lines covered (31.87%)

26426.11 hits per line

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

0.0
/ui/src/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
    {
459
        foreach (FixtureConsole *fc, m_consoleList.values())
×
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
    {
479
        foreach (FixtureConsole *fc, m_consoleList.values())
×
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();
×
500
            if (fc->hasSelections())
×
501
                m_copyFromSelection = true;
×
502
            else
503
                m_copyFromSelection = false;
×
504
            clipboard->copyContent(m_scene->id(), copyList);
×
505
        }
506
    }
507
    else
508
    {
509
        bool oneHasSelection = false;
510
        QList <SceneValue> selectedOnlyList;
511
        foreach (FixtureConsole *fc, m_consoleList.values())
×
512
        {
513
            if (fc == NULL)
×
514
                continue;
×
515
            copyList.append(fc->values());
×
516
            if (fc->hasSelections())
×
517
            {
518
                oneHasSelection = true;
519
                selectedOnlyList.append(fc->values());
×
520
            }
521
        }
522
        m_copyFromSelection = oneHasSelection;
×
523
        if (m_copyFromSelection == true)
×
524
            clipboard->copyContent(m_scene->id(), selectedOnlyList);
×
525
        else
526
            clipboard->copyContent(m_scene->id(), copyList);
×
527
    }
×
528
    if (copyList.count() > 0)
×
529
        m_pasteAction->setEnabled(true);
×
530
}
×
531

532
void SceneEditor::slotPaste()
×
533
{
534
    QLCClipboard *clipboard = m_doc->clipboard();
×
535

536
    if (clipboard->hasSceneValues() == false)
×
537
        return;
538

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

563
void SceneEditor::slotCopyToAll()
×
564
{
565
    slotCopy();
×
566

567
    QLCClipboard *clipboard = m_doc->clipboard();
×
568

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

579
    //m_copy.clear();
580
    m_pasteAction->setEnabled(false);
×
581
}
×
582

583
void SceneEditor::slotColorTool()
×
584
{
585
    QColor color = slotColorSelectorChanged(QColor());
×
586

587
    QColorDialog dialog(color, this);
×
588
    connect(&dialog, SIGNAL(currentColorChanged(const QColor&)),
×
589
            this, SLOT(slotColorSelectorChanged(const QColor&)));
590

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

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

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

611
        Q_ASSERT(fxi != NULL);
612

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

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

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

635
                     pos.setX(v);
636
                 }
637
             }
638

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

651
                     pos.setY(v);
652
                 }
653
             }
654
        }
655

656
        PositionTool dialog(pos, range);
×
657
        connect(&dialog, SIGNAL(currentPositionChanged(const QPointF&)),
×
658
            this, SLOT(slotPositionSelectorChanged(const QPointF&)));
659

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

668
QColor SceneEditor::slotColorSelectorChanged(const QColor& color)
×
669
{
670
    QColor returnColor = QColor();
×
671

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

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

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

700
                foreach (quint32 ch, magenta)
×
701
                {
702
                    fc->setChecked(true, ch);
×
703
                    fc->setValue(ch, color.magenta());
×
704
                }
705

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

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

728
                foreach (quint32 ch, green)
×
729
                {
730
                    fc->setChecked(true, ch);
×
731
                    fc->setValue(ch, color.green());
×
732
                }
733

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

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

771
    return returnColor;
772
}
773

774
void SceneEditor::slotPositionSelectorChanged(const QPointF& position)
×
775
{
776
    qreal x = position.x();
777
    qreal y = position.y();
778

779
    uchar panMsbNew = x;
×
780
    uchar panLsbNew = (x - floor(x)) * 256;
×
781
    uchar tiltMsbNew = y;
×
782
    uchar tiltLsbNew = (y - floor(y)) * 256;
×
783

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

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

798
             if (panMsbChannel != QLCChannel::invalid())
×
799
             {
800
                 fc->setChecked(true, panMsbChannel);
×
801
                 fc->setValue(panMsbChannel, panMsbNew);
×
802

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

810
             if (tiltMsbChannel != QLCChannel::invalid())
×
811
             {
812
                 fc->setChecked(true, tiltMsbChannel);
×
813
                 fc->setValue(tiltMsbChannel, tiltMsbNew);
×
814

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

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

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

864
    m_scene->setUiStateValue(UI_STATE_SHOW_DIAL, state);
×
865
}
×
866

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

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

887
    if (m_source != NULL)
×
888
        m_source->setOutputEnabled(!state);
×
889
}
×
890

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

904
}
×
905

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

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

927
            scrollArea->setWidgetResizable(true);
×
928
            int tIdx = m_tab->addTab(scrollArea, tr("All fixtures"));
×
929
            m_tab->setTabToolTip(tIdx, tr("All fixtures"));
×
930

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

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

952
                connect(console, SIGNAL(valueChanged(quint32,quint32,uchar)),
×
953
                        this, SLOT(slotValueChanged(quint32,quint32,uchar)));
954
                connect(console, SIGNAL(checked(quint32,quint32,bool)),
×
955
                        this, SLOT(slotChecked(quint32,quint32,bool)));
956

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

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

983
            addFixtureTab(fixture);
×
984

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

997
    m_scene->setUiStateValue(UI_STATE_TAB_MODE, tabbed ? UI_STATE_TABBED_FIXTURES : UI_STATE_ALL_FIXTURES);
×
998

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

1013
    m_scene->setUiStateValue(UI_STATE_TAB_INDEX, m_tab->currentIndex());
×
1014
}
×
1015

1016
void SceneEditor::slotRecord()
×
1017
{
1018
    Chaser* chaser = selectedChaser();
×
1019
    if (chaser == NULL)
×
1020
        return;
×
1021

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

1029
    // Switch to the cloned scene
1030
    FunctionManager::instance()->selectFunction(clone->id());
×
1031
}
×
1032

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

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

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

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

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

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

1106
bool SceneEditor::isPositionToolAvailable()
×
1107
{
1108
    Fixture* fxi = NULL;
1109

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

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

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

1139
    return false;
1140
}
1141

1142
void SceneEditor::createSpeedDials()
×
1143
{
1144
    if (m_speedDials != NULL)
×
1145
        return;
1146

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

1160
void SceneEditor::slotDialDestroyed(QObject *)
×
1161
{
1162
    m_speedDialAction->setChecked(false);
×
1163
}
×
1164

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

1174
/*****************************************************************************
1175
 * General page
1176
 *****************************************************************************/
1177

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

1189
    return NULL;
1190
}
×
1191

1192
QList <Fixture*> SceneEditor::selectedFixtures() const
×
1193
{
1194
    QListIterator <QTreeWidgetItem*> it(m_tree->selectedItems());
×
1195
    QList <Fixture*> list;
1196

1197
    while (it.hasNext() == true)
×
1198
    {
1199
        QTreeWidgetItem* item;
1200
        quint32 fxi_id;
1201
        Fixture* fixture;
1202

1203
        item = it.next();
×
1204
        fxi_id = item->text(KColumnID).toInt();
×
1205
        fixture = m_doc->fixture(fxi_id);
×
1206
        Q_ASSERT(fixture != NULL);
1207

1208
        list.append(fixture);
×
1209
    }
1210

1211
    return list;
×
1212
}
×
1213

1214
bool SceneEditor::addFixtureItem(Fixture* fixture)
×
1215
{
1216
    Q_ASSERT(fixture != NULL);
1217

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

1230
    QTreeWidgetItem* item;
1231

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

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

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

1252
    return true;
×
1253
}
1254

1255
void SceneEditor::removeFixtureItem(quint32 fixtureID)
×
1256
{
1257
    QTreeWidgetItem *item;
1258

1259
    item = fixtureItem(fixtureID);
×
1260
    delete item;
×
1261
}
×
1262

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

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

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

1294
            addFixtureItem(fixture);
×
1295
            addFixtureTab(fixture);
×
1296

1297
            // Add fixture in scene
1298
            m_scene->addFixture(fixture->id());
×
1299
        }
1300
    }
1301
}
×
1302

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

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

1318
            removeFixtureTab(fixture->id());
×
1319
            removeFixtureItem(fixture->id());
×
1320

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

1325
            // Remove fixture from scene
1326
            m_scene->removeFixture(fixture->id());
×
1327
        }
1328
    }
1329
}
×
1330

1331
void SceneEditor::slotEnableAll()
×
1332
{
1333
    foreach (FixtureConsole* fc, m_consoleList.values())
×
1334
    {
1335
        if (fc != NULL)
×
1336
            fc->setChecked(true);
×
1337
    }
1338
}
×
1339

1340
void SceneEditor::slotDisableAll()
×
1341
{
1342
    foreach (FixtureConsole* fc, m_consoleList.values())
×
1343
    {
1344
        if (fc != NULL)
×
1345
            fc->setChecked(false);
×
1346
    }
1347
}
×
1348

1349
void SceneEditor::slotFadeInChanged(int ms)
×
1350
{
1351
    m_scene->setFadeInSpeed(ms);
×
1352
}
×
1353

1354
void SceneEditor::slotFadeOutChanged(int ms)
×
1355
{
1356
    m_scene->setFadeOutSpeed(ms);
×
1357
}
×
1358

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

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

1377
void SceneEditor::slotChannelGroupsChanged(QTreeWidgetItem *item, int column)
×
1378
{
1379
    if (item == NULL)
×
1380
        return;
1381

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

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

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

1415
    updateChannelsGroupsTab();
×
1416
}
1417

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

1426
    if (m_channelGroupsTree->topLevelItemCount() == 0)
×
1427
    {
1428
        m_fixtureFirstTabIndex = 1;
×
1429
        return;
×
1430
    }
1431

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

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

1465
    m_channelGroupsTab = 1;
×
1466
    m_fixtureFirstTabIndex = 2;
×
1467
    connect(console, SIGNAL(groupValueChanged(quint32,uchar)),
×
1468
            this, SLOT(slotGroupValueChanged(quint32,uchar)));
1469
}
×
1470

1471
GroupsConsole *SceneEditor::groupConsoleTab(int tab)
×
1472
{
1473
    if (tab != m_channelGroupsTab)
×
1474
        return NULL;
1475

1476
    QScrollArea* area = qobject_cast<QScrollArea*> (m_tab->widget(tab));
×
1477
    Q_ASSERT(area != NULL);
1478

1479
    return qobject_cast<GroupsConsole*> (area->widget());
×
1480
}
1481

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

1505
/*****************************************************************************
1506
 * Fixture tabs
1507
 *****************************************************************************/
1508

1509
FixtureConsole* SceneEditor::fixtureConsole(Fixture* fixture)
×
1510
{
1511
    Q_ASSERT(fixture != NULL);
1512

1513
    if (m_consoleList.contains(fixture->id()))
×
1514
        return m_consoleList[fixture->id()];
×
1515

1516
    return NULL;
1517
}
1518

1519
void SceneEditor::addFixtureTab(Fixture* fixture, quint32 channel)
×
1520
{
1521
    Q_ASSERT(fixture != NULL);
1522

1523
    /* Put the console inside a scroll area */
1524
    QScrollArea* scrollArea = new QScrollArea(m_tab);
×
1525
    scrollArea->setWidgetResizable(true);
×
1526

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

1534
    /* Start off with all channels disabled */
1535
    console->setChecked(false);
×
1536

1537
    connect(console, SIGNAL(valueChanged(quint32,quint32,uchar)),
×
1538
            this, SLOT(slotValueChanged(quint32,quint32,uchar)));
1539
    connect(console, SIGNAL(checked(quint32,quint32,bool)),
×
1540
            this, SLOT(slotChecked(quint32,quint32,bool)));
1541

1542
    if (channel != QLCChannel::invalid())
×
1543
        console->setChecked(true, channel);
×
1544
}
×
1545

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

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

1572
    QScrollArea* area = qobject_cast<QScrollArea*> (m_tab->widget(tab));
×
1573
    Q_ASSERT(area != NULL);
1574

1575
    return qobject_cast<FixtureConsole*> (area->widget());
×
1576
}
1577

1578
void SceneEditor::setTabChannelState(bool status, Fixture *fixture, quint32 channel)
×
1579
{
1580
    Q_ASSERT(fixture != NULL);
1581

1582
    if (channel == QLCChannel::invalid())
×
1583
        return;
1584

1585
    if (m_consoleList.contains(fixture->id()))
×
1586
        m_consoleList[fixture->id()]->setChecked(status, channel);
×
1587
}
1588

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

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

1603
    if (m_source != NULL)
×
1604
        m_source->set(fxi, channel, value);
×
1605
}
×
1606

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

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

1635
void SceneEditor::slotGoToPreviousTab()
×
1636
{
1637
    if (m_currentTab == 0)
×
1638
        m_currentTab = m_tab->count() - 1;
×
1639
    else
1640
        m_currentTab--;
×
1641
    m_tab->setCurrentIndex(m_currentTab);
×
1642
}
×
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