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

mcallegari / qlcplus / 19144422256

06 Nov 2025 05:33PM UTC coverage: 34.256% (-0.1%) from 34.358%
19144422256

push

github

mcallegari
Back to 5.1.0 debug

17718 of 51723 relevant lines covered (34.26%)

19528.23 hits per line

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

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

5
  Copyright (C) Massimo Callegari
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 <QInputDialog>
21
#include <QColorDialog>
22
#include <QMessageBox>
23
#include <QFileDialog>
24
#include <QVBoxLayout>
25
#include <QMouseEvent>
26
#include <QScrollBar>
27
#include <QComboBox>
28
#include <QSplitter>
29
#include <QSettings>
30
#include <QToolBar>
31
#include <QSpinBox>
32
#include <QLabel>
33
#include <QDebug>
34
#include <QUrl>
35

36
#include "functionselection.h"
37
#include "audioplugincache.h"
38
#include "rgbmatrixeditor.h"
39
#include "multitrackview.h"
40
#include "chasereditor.h"
41
#include "audioeditor.h"
42
#include "efxeditor.h"
43
#include "videoeditor.h"
44
#include "showmanager.h"
45
#include "sceneeditor.h"
46
#include "timingstool.h"
47
#include "qlcmacros.h"
48
#include "sequence.h"
49
#include "chaser.h"
50

51
#define SETTINGS_HSPLITTER "showmanager/hsplitter"
52
#define SETTINGS_VSPLITTER "showmanager/vsplitter"
53

54
ShowManager* ShowManager::s_instance = NULL;
55

56
ShowManager::ShowManager(QWidget* parent, Doc* doc)
×
57
    : QWidget(parent)
58
    , m_doc(doc)
×
59
    , m_show(NULL)
×
60
    , m_currentTrack(NULL)
×
61
    , m_currentScene(NULL)
×
62
    , m_sceneEditor(NULL)
×
63
    , m_currentEditor(NULL)
×
64
    , m_editorFunctionID(Function::invalidId())
×
65
    , m_selectedShowIndex(-1)
×
66
    , cursorMovedDuringPause(false)
×
67
    , m_splitter(NULL)
×
68
    , m_vsplitter(NULL)
×
69
    , m_showview(NULL)
×
70
    , m_toolbar(NULL)
×
71
    , m_showsCombo(NULL)
×
72
    , m_addShowAction(NULL)
×
73
    , m_addTrackAction(NULL)
×
74
    , m_addSequenceAction(NULL)
×
75
    , m_addAudioAction(NULL)
×
76
    , m_addVideoAction(NULL)
×
77
    , m_copyAction(NULL)
×
78
    , m_pasteAction(NULL)
×
79
    , m_deleteAction(NULL)
×
80
    , m_colorAction(NULL)
×
81
    , m_lockAction(NULL)
×
82
    , m_timingsAction(NULL)
×
83
    , m_snapGridAction(NULL)
×
84
    , m_stopAction(NULL)
×
85
    , m_playAction(NULL)
×
86
{
87
    Q_ASSERT(s_instance == NULL);
×
88
    s_instance = this;
×
89

90
    Q_ASSERT(doc != NULL);
×
91

92
    new QVBoxLayout(this);
×
93
    layout()->setContentsMargins(0, 0, 0, 0);
×
94
    layout()->setSpacing(0);
×
95

96
    initActions();
×
97
    initToolbar();
×
98

99
    m_splitter = new QSplitter(Qt::Vertical, this);
×
100
    layout()->addWidget(m_splitter);
×
101
    //initMultiTrackView();
102
    m_showview = new MultiTrackView();
×
103
    // add container for multitrack & function editors view
104
    QWidget* gcontainer = new QWidget(this);
×
105
    m_splitter->addWidget(gcontainer);
×
106
    gcontainer->setLayout(new QVBoxLayout);
×
107
    gcontainer->layout()->setContentsMargins(0, 0, 0, 0);
×
108

109
    m_showview->setRenderHint(QPainter::Antialiasing);
×
110
    m_showview->setAcceptDrops(true);
×
111
    m_showview->setAlignment(Qt::AlignLeft | Qt::AlignTop);
×
112
    m_showview->setBackgroundBrush(QBrush(QColor(88, 88, 88, 255), Qt::SolidPattern));
×
113
    connect(m_showview, SIGNAL(viewClicked(QMouseEvent *)),
×
114
            this, SLOT(slotViewClicked(QMouseEvent *)));
115

116
    connect(m_showview, SIGNAL(showItemMoved(ShowItem*,quint32,bool)),
×
117
            this, SLOT(slotShowItemMoved(ShowItem*,quint32,bool)));
118
    connect(m_showview, SIGNAL(timeChanged(quint32)),
×
119
            this, SLOT(slotUpdateTime(quint32)));
120
    connect(m_showview, SIGNAL(trackClicked(Track*)),
×
121
            this, SLOT(slotTrackClicked(Track*)));
122
    connect(m_showview, SIGNAL(trackDoubleClicked(Track*)),
×
123
            this, SLOT(slotTrackDoubleClicked(Track*)));
124
    connect(m_showview, SIGNAL(trackMoved(Track*,int)),
×
125
            this, SLOT(slotTrackMoved(Track*,int)));
126
    connect(m_showview, SIGNAL(trackDelete(Track*)),
×
127
            this, SLOT(slotTrackDelete(Track*)));
128

129
    // split the multitrack view into two (left: tracks, right: function editors)
130
    m_vsplitter = new QSplitter(Qt::Horizontal, this);
×
131
    m_splitter->widget(0)->layout()->addWidget(m_vsplitter);
×
132
    QWidget* mcontainer = new QWidget(this);
×
133
    mcontainer->setLayout(new QHBoxLayout);
×
134
    mcontainer->layout()->setContentsMargins(0, 0, 0, 0);
×
135
    m_vsplitter->addWidget(mcontainer);
×
136
    m_vsplitter->widget(0)->layout()->addWidget(m_showview);
×
137

138
    // add container for function editors
139
    QWidget* ccontainer = new QWidget(this);
×
140
    m_vsplitter->addWidget(ccontainer);
×
141
    ccontainer->setLayout(new QVBoxLayout);
×
142
    ccontainer->layout()->setContentsMargins(0, 0, 0, 0);
×
143
    m_vsplitter->widget(1)->hide();
×
144

145
    // add container for scene editor
146
    QWidget* container = new QWidget(this);
×
147
    m_splitter->addWidget(container);
×
148
    container->setLayout(new QVBoxLayout);
×
149
    container->layout()->setContentsMargins(0, 0, 0, 0);
×
150
    m_splitter->widget(1)->hide();
×
151

152
    connect(m_doc, SIGNAL(clearing()), this, SLOT(slotDocClearing()));
×
153
    connect(m_doc, SIGNAL(functionRemoved(quint32)), this, SLOT(slotFunctionRemoved(quint32)));
×
154
    connect(m_doc, SIGNAL(loaded()), this, SLOT(slotDocLoaded()));
×
155

156
    QSettings settings;
×
157
    QVariant var = settings.value(SETTINGS_HSPLITTER);
×
158
    if (var.isValid() == true)
×
159
        m_splitter->restoreState(var.toByteArray());
×
160
    else
161
        m_splitter->setSizes(QList <int> () << int(this->width() / 2) << int(this->width() / 2));
×
162

163
    QVariant var2 = settings.value(SETTINGS_VSPLITTER);
×
164
    if (var2.isValid() == true)
×
165
        m_vsplitter->restoreState(var2.toByteArray());
×
166
    else
167
        m_vsplitter->setSizes(QList <int> () << int(this->width() / 2) << int(this->width() / 2));
×
168
}
×
169

170
ShowManager::~ShowManager()
×
171
{
172
    QSettings settings;
×
173
    settings.setValue(SETTINGS_HSPLITTER, m_splitter->saveState());
×
174
    settings.setValue(SETTINGS_VSPLITTER, m_vsplitter->saveState());
×
175

176
    ShowManager::s_instance = NULL;
×
177
}
×
178

179
ShowManager* ShowManager::instance()
×
180
{
181
    return s_instance;
×
182
}
183

184
void ShowManager::clearContents()
×
185
{
186
    hideRightEditor();
×
187
    showSceneEditor(NULL);
×
188
    m_showview->resetView();
×
189
    m_showsCombo->clear();
×
190
    m_show = NULL;
×
191
    m_currentScene = NULL;
×
192
    m_currentTrack = NULL;
×
193
}
×
194

195
void ShowManager::initActions()
×
196
{
197
    /* Manage actions */
198
    m_addShowAction = new QAction(QIcon(":/show.png"),
×
199
                                   tr("New s&how"), this);
×
200
    m_addShowAction->setShortcut(QKeySequence("CTRL+H"));
×
201
    connect(m_addShowAction, SIGNAL(triggered(bool)),
×
202
            this, SLOT(slotAddShow()));
203

204
    m_addTrackAction = new QAction(QIcon(":/edit_add.png"),
×
205
                                   tr("Add a &track or an existing function"), this);
×
206
    m_addTrackAction->setShortcut(QKeySequence("CTRL+N"));
×
207
    connect(m_addTrackAction, SIGNAL(triggered(bool)),
×
208
            this, SLOT(slotAddItem()));
209

210
    m_addSequenceAction = new QAction(QIcon(":/sequence.png"),
×
211
                                    tr("New s&equence"), this);
×
212
    m_addSequenceAction->setShortcut(QKeySequence("CTRL+E"));
×
213
    connect(m_addSequenceAction, SIGNAL(triggered(bool)),
×
214
            this, SLOT(slotAddSequence()));
215

216
    m_addAudioAction = new QAction(QIcon(":/audio.png"),
×
217
                                    tr("New &audio"), this);
×
218
    m_addAudioAction->setShortcut(QKeySequence("CTRL+A"));
×
219
    connect(m_addAudioAction, SIGNAL(triggered(bool)),
×
220
            this, SLOT(slotAddAudio()));
221

222
    m_addVideoAction = new QAction(QIcon(":/video.png"),
×
223
                                    tr("New vi&deo"), this);
×
224
    m_addVideoAction->setShortcut(QKeySequence("CTRL+D"));
×
225
    connect(m_addVideoAction, SIGNAL(triggered(bool)),
×
226
            this, SLOT(slotAddVideo()));
227

228
    /* Edit actions */
229
    m_copyAction = new QAction(QIcon(":/editcopy.png"),
×
230
                                tr("&Copy"), this);
×
231
    m_copyAction->setShortcut(QKeySequence("CTRL+C"));
×
232
    connect(m_copyAction, SIGNAL(triggered(bool)),
×
233
            this, SLOT(slotCopy()));
234
    m_copyAction->setEnabled(false);
×
235

236
    m_pasteAction = new QAction(QIcon(":/editpaste.png"),
×
237
                               tr("&Paste"), this);
×
238
    m_pasteAction->setShortcut(QKeySequence("CTRL+V"));
×
239
    connect(m_pasteAction, SIGNAL(triggered(bool)),
×
240
            this, SLOT(slotPaste()));
241
    m_pasteAction->setEnabled(false);
×
242

243
    m_deleteAction = new QAction(QIcon(":/editdelete.png"),
×
244
                                 tr("&Delete"), this);
×
245
    m_deleteAction->setShortcut(QKeySequence("Delete"));
×
246
    connect(m_deleteAction, SIGNAL(triggered(bool)),
×
247
            this, SLOT(slotDelete()));
248
    m_deleteAction->setEnabled(false);
×
249

250
    m_colorAction = new QAction(QIcon(":/color.png"),
×
251
                                tr("Change Co&lor"), this);
×
252
    m_colorAction->setShortcut(QKeySequence("CTRL+L"));
×
253
    connect(m_colorAction, SIGNAL(triggered(bool)),
×
254
           this, SLOT(slotChangeColor()));
255
    m_colorAction->setEnabled(false);
×
256

257
    m_lockAction = new QAction(QIcon(":/lock.png"),
×
258
                               tr("Lock item"), this);
×
259
    m_lockAction->setShortcut(QKeySequence("CTRL+K"));
×
260
    connect(m_lockAction, SIGNAL(triggered()),
×
261
            this, SLOT(slotChangeLock()));
262
    m_lockAction->setEnabled(false);
×
263

264
    m_timingsAction = new QAction(QIcon(":/speed.png"),
×
265
                                  tr("Item start time and duration"), this);
×
266
    m_timingsAction->setShortcut(QKeySequence("CTRL+T"));
×
267
    connect(m_timingsAction, SIGNAL(triggered()),
×
268
            this, SLOT(slotShowTimingsTool()));
269
    m_timingsAction->setEnabled(false);
×
270

271
    m_snapGridAction = new QAction(QIcon(":/grid.png"),
×
272
                                   tr("Snap to &Grid"), this);
×
273
    m_snapGridAction->setShortcut(QKeySequence("CTRL+G"));
×
274
    m_snapGridAction->setCheckable(true);
×
275
    connect(m_snapGridAction, SIGNAL(triggered(bool)),
×
276
           this, SLOT(slotToggleSnapToGrid(bool)));
277

278
    m_stopAction = new QAction(QIcon(":/player_stop.png"),
×
279
                                 tr("St&op"), this);
×
280
    m_stopAction->setShortcut(QKeySequence("CTRL+SPACE"));
×
281
    connect(m_stopAction, SIGNAL(triggered(bool)),
×
282
            this, SLOT(slotStopPlayback()));
283

284
    m_playAction = new QAction(QIcon(":/player_play.png"),
×
285
                                 tr("&Play"), this);
×
286
    m_playAction->setShortcut(QKeySequence("SPACE"));
×
287
    connect(m_playAction, SIGNAL(triggered(bool)),
×
288
            this, SLOT(slotStartPlayback()));
289
}
×
290

291
void ShowManager::initToolbar()
×
292
{
293
    // Add a toolbar to the dock area
294
    m_toolbar = new QToolBar("Show Manager", this);
×
295
    m_toolbar->setFloatable(false);
×
296
    m_toolbar->setMovable(false);
×
297
    layout()->addWidget(m_toolbar);
×
298
    m_toolbar->addAction(m_addShowAction);
×
299
    m_showsCombo = new QComboBox();
×
300
    m_showsCombo->setFixedWidth(250);
×
301
    m_showsCombo->setMaxVisibleItems(30);
×
302
    connect(m_showsCombo, SIGNAL(currentIndexChanged(int)),
×
303
            this, SLOT(slotShowsComboChanged(int)));
304
    m_toolbar->addWidget(m_showsCombo);
×
305
    m_toolbar->addSeparator();
×
306

307
    m_toolbar->addAction(m_addTrackAction);
×
308
    m_toolbar->addAction(m_addSequenceAction);
×
309
    m_toolbar->addAction(m_addAudioAction);
×
310
    m_toolbar->addAction(m_addVideoAction);
×
311

312
    m_toolbar->addSeparator();
×
313
    m_toolbar->addAction(m_copyAction);
×
314
    m_toolbar->addAction(m_pasteAction);
×
315
    m_toolbar->addAction(m_deleteAction);
×
316
    m_toolbar->addSeparator();
×
317

318
    m_toolbar->addAction(m_colorAction);
×
319
    m_toolbar->addAction(m_lockAction);
×
320
    m_toolbar->addAction(m_timingsAction);
×
321
    m_toolbar->addAction(m_snapGridAction);
×
322
    m_toolbar->addSeparator();
×
323

324
    // Time label and playback buttons
325
    m_timeLabel = new QLabel("00:00:00.00");
×
326
    m_timeLabel->setFixedWidth(150);
×
327
    m_timeLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
×
328
    QFont timeFont = QApplication::font();
×
329
    timeFont.setBold(true);
×
330
    timeFont.setPixelSize(20);
×
331
    m_timeLabel->setFont(timeFont);
×
332
    m_toolbar->addWidget(m_timeLabel);
×
333
    m_toolbar->addSeparator();
×
334

335
    m_toolbar->addAction(m_stopAction);
×
336
    m_toolbar->addAction(m_playAction);
×
337

338
    /* Create an empty widget between help items to flush them to the right */
339
    QWidget* widget = new QWidget(this);
×
340
    widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
×
341
    m_toolbar->addWidget(widget);
×
342

343
    /* Add time division elements */
344
    QLabel* timeLabel = new QLabel(tr("Time division:"));
×
345
    m_toolbar->addWidget(timeLabel);
×
346

347
    m_timeDivisionCombo = new QComboBox();
×
348
    m_timeDivisionCombo->setFixedWidth(100);
×
349
    m_timeDivisionCombo->addItem(tr("Time"), Show::Time);
×
350
    m_timeDivisionCombo->addItem("BPM 4/4", Show::BPM_4_4);
×
351
    m_timeDivisionCombo->addItem("BPM 3/4", Show::BPM_3_4);
×
352
    m_timeDivisionCombo->addItem("BPM 2/4", Show::BPM_2_4);
×
353
    m_toolbar->addWidget(m_timeDivisionCombo);
×
354
    connect(m_timeDivisionCombo, SIGNAL(currentIndexChanged(int)),
×
355
            this, SLOT(slotTimeDivisionTypeChanged(int)));
356

357
    m_bpmField = new QSpinBox();
×
358
    m_bpmField->setFixedWidth(70);
×
359
    m_bpmField->setMinimum(10);
×
360
    m_bpmField->setMaximum(240);
×
361
    m_bpmField->setValue(120);
×
362
    m_bpmField->setEnabled(false);
×
363
    m_toolbar->addWidget(m_bpmField);
×
364
    connect(m_bpmField, SIGNAL(valueChanged(int)),
×
365
            this, SLOT(slotBPMValueChanged(int)));
366
}
×
367

368
/*********************************************************************
369
 * Shows combo
370
 *********************************************************************/
371
void ShowManager::updateShowsCombo()
×
372
{
373
    int oldIndex = m_showsCombo->currentIndex();
×
374

375
    // protect poor Show Manager from drawing all the shows
376
    disconnect(m_showsCombo, SIGNAL(currentIndexChanged(int)),
×
377
            this, SLOT(slotShowsComboChanged(int)));
378

379
    m_showsCombo->clear();
×
380
    foreach (Function* f, m_doc->functionsByType(Function::ShowType))
×
381
    {
382
        // Insert in ascii order
383
        int insertPosition = 0;
×
384
        while (insertPosition < m_showsCombo->count() &&
×
385
               QString::localeAwareCompare(m_showsCombo->itemText(insertPosition), f->name()) <= 0)
×
386
                    ++insertPosition;
×
387
        m_showsCombo->insertItem(insertPosition, f->name(), QVariant(f->id()));
×
388
    }
×
389
    if (m_showsCombo->count() > 0)
×
390
    {
391
        m_addTrackAction->setEnabled(true);
×
392
    }
393
    else
394
    {
395
        m_addTrackAction->setEnabled(false);
×
396
        m_addSequenceAction->setEnabled(false);
×
397
        m_addAudioAction->setEnabled(false);
×
398
        m_addVideoAction->setEnabled(false);
×
399
    }
400

401
    if (m_show == NULL || m_show->getTracksCount() == 0)
×
402
    {
403
        m_deleteAction->setEnabled(false);
×
404
        m_pasteAction->setEnabled(false);
×
405
    }
406
    else
407
    {
408
        if (m_doc->clipboard()->hasFunction())
×
409
            m_pasteAction->setEnabled(true);
×
410
        m_deleteAction->setEnabled(true);
×
411
    }
412

413
    connect(m_showsCombo, SIGNAL(currentIndexChanged(int)),
×
414
            this, SLOT(slotShowsComboChanged(int)));
415

416
    if (m_showsCombo->count() == 0)
×
417
    {
418
        m_showview->resetView();
×
419
        m_show = NULL;
×
420
        m_currentScene = NULL;
×
421
        m_currentTrack = NULL;
×
422
        return;
×
423
    }
424

425
    if (m_selectedShowIndex < 0 || m_selectedShowIndex >= m_showsCombo->count())
×
426
        m_selectedShowIndex = 0;
×
427

428
    m_showsCombo->setCurrentIndex(m_selectedShowIndex);
×
429

430
    if (oldIndex != m_selectedShowIndex)
×
431
        updateMultiTrackView();
×
432
}
433

434
void ShowManager::slotShowsComboChanged(int idx)
×
435
{
436
    qDebug() << Q_FUNC_INFO << "Idx: " << idx;
×
437
    if (m_selectedShowIndex != idx)
×
438
    {
439
        m_selectedShowIndex = idx;
×
440
        hideRightEditor();
×
441
        updateMultiTrackView();
×
442
    }
443
}
×
444

445
void ShowManager::showSceneEditor(Scene *scene)
×
446
{
447
    if (m_sceneEditor != NULL)
×
448
    {
449
        emit functionManagerActive(false);       
×
450
        m_splitter->widget(1)->layout()->removeWidget(m_sceneEditor);
×
451
        m_splitter->widget(1)->hide();
×
452
        delete m_sceneEditor;
×
453
        m_sceneEditor = NULL;
×
454
    }
455

456
    if (scene == NULL)
×
457
        return;
×
458

459
    if (this->isVisible())
×
460
    {
461
        m_sceneEditor = new SceneEditor(m_splitter->widget(1), scene, m_doc, false);
×
462
        if (m_sceneEditor != NULL)
×
463
        {
464
            m_splitter->widget(1)->layout()->addWidget(m_sceneEditor);
×
465
            m_splitter->widget(1)->show();
×
466

467
            connect(this, SIGNAL(functionManagerActive(bool)),
×
468
                    m_sceneEditor, SLOT(slotFunctionManagerActive(bool)));
×
469
        }
470
    }
471
}
472

473
void ShowManager::hideRightEditor()
×
474
{
475
    if (m_currentEditor != NULL)
×
476
    {
477
        m_vsplitter->widget(1)->layout()->removeWidget(m_currentEditor);
×
478
        m_vsplitter->widget(1)->hide();
×
479
        delete m_currentEditor;
×
480
        m_currentEditor = NULL;
×
481
        m_editorFunctionID = Function::invalidId();
×
482
    }
483
}
×
484

485
void ShowManager::showRightEditor(Function *function)
×
486
{
487
    if (function != NULL && m_editorFunctionID == function->id())
×
488
        return;
×
489

490
    hideRightEditor();
×
491

492
    if (function == NULL || this->isVisible() == false)
×
493
        return;
×
494

495
    if (function->type() == Function::ChaserType)
×
496
    {
497
        Chaser *chaser = qobject_cast<Chaser*> (function);
×
498
        m_currentEditor = new ChaserEditor(m_vsplitter->widget(1), chaser, m_doc);
×
499
        if (m_currentEditor != NULL)
×
500
        {
501
            connect(m_currentEditor, SIGNAL(stepSelectionChanged(int)),
×
502
                    this, SLOT(slotStepSelectionChanged(int)));
503
        }
504
    }
505
    else if (function->type() == Function::SequenceType)
×
506
    {
507
        Sequence *sequence = qobject_cast<Sequence*> (function);
×
508
        m_currentEditor = new ChaserEditor(m_vsplitter->widget(1), sequence, m_doc);
×
509
        if (m_currentEditor != NULL)
×
510
        {
511
            ChaserEditor *editor = qobject_cast<ChaserEditor*>(m_currentEditor);
×
512

513
            editor->showOrderAndDirection(false);
×
514

515
            /** Signal from chaser editor to scene editor.
516
             *  When a step is clicked apply values immediately */
517
            connect(m_currentEditor, SIGNAL(applyValues(QList<SceneValue>&)),
×
518
                    m_sceneEditor, SLOT(slotSetSceneValues(QList <SceneValue>&)));
×
519

520
            /** Signal from scene editor to chaser editor.
521
             *  When a fixture value is changed, update the selected chaser step */
522
            connect(m_sceneEditor, SIGNAL(fixtureValueChanged(SceneValue,bool)),
×
523
                    m_currentEditor, SLOT(slotUpdateCurrentStep(SceneValue,bool)));
×
524

525
            connect(m_currentEditor, SIGNAL(stepSelectionChanged(int)),
×
526
                    this, SLOT(slotStepSelectionChanged(int)));
527
        }
528
    }
529
    else if (function->type() == Function::AudioType)
×
530
    {
531
        m_currentEditor = new AudioEditor(m_vsplitter->widget(1), qobject_cast<Audio*> (function), m_doc);
×
532
    }
533
    else if (function->type() == Function::RGBMatrixType)
×
534
    {
535
        m_currentEditor = new RGBMatrixEditor(m_vsplitter->widget(1), qobject_cast<RGBMatrix*> (function), m_doc);
×
536
    }
537
    else if (function->type() == Function::EFXType)
×
538
    {
539
        m_currentEditor = new EFXEditor(m_vsplitter->widget(1), qobject_cast<EFX*> (function), m_doc);
×
540
    }
541
    else if (function->type() == Function::VideoType)
×
542
    {
543
        m_currentEditor = new VideoEditor(m_vsplitter->widget(1), qobject_cast<Video*> (function), m_doc);
×
544
    }
545
    else
546
        return;
×
547

548
    if (m_currentEditor != NULL)
×
549
    {
550
        m_vsplitter->widget(1)->layout()->addWidget(m_currentEditor);
×
551
        m_vsplitter->widget(1)->show();
×
552
        m_currentEditor->show();
×
553
        m_editorFunctionID = function->id();
×
554
    }
555

556
}
557

558
void ShowManager::slotAddShow()
×
559
{
560
    bool ok;
561
    QString defaultName = QString("%1 %2").arg(tr("New Show")).arg(m_doc->nextFunctionID());
×
562
    QString showName = QInputDialog::getText(this, tr("Show name setup"),
×
563
                                         tr("Show name:"), QLineEdit::Normal,
×
564
                                         defaultName, &ok);
×
565

566
    if (ok == true)
×
567
    {
568
        m_show = new Show(m_doc);
×
569
        if (showName.isEmpty() == false)
×
570
            m_show->setName(showName);
×
571
        else
572
            m_show->setName(defaultName);
×
573
        Function *f = qobject_cast<Function*>(m_show);
×
574
        if (m_doc->addFunction(f) == true)
×
575
        {
576
            // modify the new selected Show index
577
            int insertPosition = 0;
×
578
            while (insertPosition < m_showsCombo->count() &&
×
579
                    QString::localeAwareCompare(m_showsCombo->itemText(insertPosition), m_show->name()) <= 0)
×
580
                ++insertPosition;
×
581
            m_selectedShowIndex = insertPosition;
×
582
            updateShowsCombo();
×
583
            m_copyAction->setEnabled(false);
×
584
            if (m_doc->clipboard()->hasFunction())
×
585
                m_pasteAction->setEnabled(true);
×
586
            showSceneEditor(NULL);
×
587
            hideRightEditor();
×
588
            m_currentScene = NULL;
×
589
            m_currentTrack = NULL;
×
590
        }
591
    }
592
}
×
593

594
void ShowManager::slotAddItem()
×
595
{
596
    if (m_show == NULL)
×
597
        return;
×
598

599
    FunctionSelection fs(this, m_doc);
×
600
    // Forbid self-containment
601
    QList<quint32> disabledList;
×
602
    foreach (Function* function, m_doc->functions())
×
603
    {
604
        if (function->contains(m_show->id()))
×
605
            disabledList << function->id();
×
606
    }
×
607
    fs.setDisabledFunctions(disabledList);
×
608

609
    fs.setMultiSelection(false);
×
610
    fs.setFilter(Function::SceneType | Function::ChaserType | Function::SequenceType | Function::AudioType | Function::RGBMatrixType | Function::EFXType);
×
611
    fs.disableFilters(Function::ShowType | Function::ScriptType | Function::CollectionType);
×
612
    fs.showNewTrack(true);
×
613

614
    if (fs.exec() == QDialog::Accepted)
×
615
    {
616
        QList <quint32> ids = fs.selection();
×
617
        if (ids.count() == 0)
×
618
            return;
×
619
        quint32 selectedID = ids.first();
×
620

621
        /**
622
         * Here there are 8 cases:
623
         * 1) a new empty track
624
         * 2) an existing scene: create a new track with a 10 seconds Sequence
625
         * 3) an existing sequence
626
         *    3.1) append to an existing track
627
         *    3.2) create a new track bound to the Sequence's Scene ID
628
         * 4) an existing chaser
629
         *    4.1) append to the selected track
630
         *    4.3) create a new track
631
         * 5) an existing audio:
632
         *    5.1) append to the selected track
633
         *    5.2) create a new track
634
         * 6) an existing RGB Matrix:
635
         *    6.1) append to the selected track
636
         *    6.2) create a new track
637
         * 7) an existing EFX:
638
         *    7.1) append to the selected track
639
         *    7.2) create a new track
640
         * 8) an existing video:
641
         *    8.1) append to the selected track
642
         *    8.2) create a new track
643
         **/
644

645
        bool createTrack = false;
×
646
        quint32 newTrackBoundID = Function::invalidId();
×
647

648
        if (selectedID == Function::invalidId())
×
649
        {
650
            createTrack = true;
×
651
        }
652
        else
653
        {
654
            Function *selectedFunc = m_doc->function(selectedID);
×
655
            if (selectedFunc == NULL) // maybe a popup here ?
×
656
                return;
×
657

658
            /** 2) an existing scene */
659
            if (selectedFunc->type() == Function::SceneType)
×
660
            {
661
                m_currentScene = qobject_cast<Scene*>(selectedFunc);
×
662
                newTrackBoundID = selectedFunc->id();
×
663
                createTrack = true;
×
664
            }
665
            else if (selectedFunc->type() == Function::ChaserType)
×
666
            {
667
                /** 4.1) add chaser to the currently selected track */
668
                if (m_currentTrack != NULL)
×
669
                {
670
                    m_showview->addSequence(qobject_cast<Chaser*>(selectedFunc), m_currentTrack);
×
671
                    m_doc->setModified();
×
672
                    return;
×
673
                }
674
                /** 4.2) It is necessary to create a new track (below) */
675
                createTrack = true;
×
676
            }
677
            else if (selectedFunc->type() == Function::SequenceType)
×
678
            {
679
                Sequence *sequence = qobject_cast<Sequence*>(selectedFunc);
×
680
                quint32 chsSceneID = sequence->boundSceneID();
×
681
                foreach (Track *track, m_show->tracks())
×
682
                {
683
                    /** 3.1) append to an existing track */
684
                    if (track->getSceneID() == chsSceneID)
×
685
                    {
686
                        Sequence *newSequence = qobject_cast<Sequence*>(sequence->createCopy(m_doc, true));
×
687
                        newSequence->setName(sequence->name() + tr(" (Copy)"));
×
688
                        newSequence->setDirection(Function::Forward);
×
689
                        newSequence->setRunOrder(Function::SingleShot);
×
690
                        m_showview->addSequence(newSequence, track);
×
691
                        m_doc->setModified();
×
692
                        return;
×
693
                    }
694
                }
×
695
                /** 3.2) It is necessary to create a new track (below) */
696
                createTrack = true;
×
697
                newTrackBoundID = sequence->boundSceneID();
×
698
                m_currentScene = qobject_cast<Scene*>(m_doc->function(newTrackBoundID));
×
699
            }
700
            else if (selectedFunc->type() == Function::AudioType)
×
701
            {
702
                /** 5.1) add audio to the currently selected track */
703
                if (m_currentTrack != NULL)
×
704
                {
705
                    m_showview->addAudio(qobject_cast<Audio*>(selectedFunc), m_currentTrack);
×
706
                    m_doc->setModified();
×
707
                    return;
×
708
                }
709
                /** 5.2) It is necessary to create a new track (below) */
710
                createTrack = true;
×
711
            }
712
            else if (selectedFunc->type() == Function::RGBMatrixType)
×
713
            {
714
                /** 6.1) add RGB Matrix to the currently selected track */
715
                if (m_currentTrack != NULL)
×
716
                {
717
                    m_showview->addRGBMatrix(qobject_cast<RGBMatrix*>(selectedFunc), m_currentTrack);
×
718
                    m_doc->setModified();
×
719
                    return;
×
720
                }
721
                /** 6.2) It is necessary to create a new track (below) */
722
                createTrack = true;
×
723
            }
724
            else if (selectedFunc->type() == Function::EFXType)
×
725
            {
726
                /** 7.1) add EFX to the currently selected track */
727
                if (m_currentTrack != NULL)
×
728
                {
729
                    m_showview->addEFX(qobject_cast<EFX*>(selectedFunc), m_currentTrack);
×
730
                    m_doc->setModified();
×
731
                    return;
×
732
                }
733
                /** 7.2) It is necessary to create a new track (below) */
734
                createTrack = true;
×
735
            }
736
            else if (selectedFunc->type() == Function::VideoType)
×
737
            {
738
                /** 8.1) add video to the currently selected track */
739
                if (m_currentTrack != NULL)
×
740
                {
741
                    m_showview->addVideo(qobject_cast<Video*>(selectedFunc), m_currentTrack);
×
742
                    m_doc->setModified();
×
743
                    return;
×
744
                }
745
                /** 8.2) It is necessary to create a new track (below) */
746
                createTrack = true;
×
747
            }
748
        }
749

750
        if (createTrack == true)
×
751
        {
752
            Track* newTrack = new Track(newTrackBoundID);
×
753
            if (newTrackBoundID != Function::invalidId() && m_currentScene != NULL)
×
754
                newTrack->setName(m_currentScene->name());
×
755
            else
756
                newTrack->setName(tr("Track %1").arg(m_show->tracks().count() + 1));
×
757

758
            m_show->addTrack(newTrack);
×
759
            m_showview->addTrack(newTrack);
×
760
            m_currentTrack = newTrack;
×
761
            if (newTrackBoundID == Function::invalidId())
×
762
                m_currentScene = NULL;
×
763
            else
764
                m_currentScene = qobject_cast<Scene*>(m_doc->function(newTrackBoundID));
×
765
        }
766

767
        if (selectedID != Function::invalidId())
×
768
        {
769
            Function *selectedFunc = m_doc->function(selectedID);
×
770
            if (selectedFunc == NULL) // maybe a popup here ?
×
771
                return;
×
772

773
            /** 2) create a 10 seconds Sequence on the current track */
774
            if (selectedFunc->type() == Function::SceneType)
×
775
            {
776
                Function* f = new Sequence(m_doc);
×
777
                Sequence *sequence = qobject_cast<Sequence*> (f);
×
778
                sequence->setBoundSceneID(m_currentScene->id());
×
779
                if (m_doc->addFunction(f) == true)
×
780
                {
781
                    sequence->setDirection(Function::Forward);
×
782
                    sequence->setRunOrder(Function::SingleShot);
×
783
                    sequence->setDurationMode(Chaser::PerStep);
×
784
                    m_currentScene->setVisible(false);
×
785
                    f->setName(QString("%1 %2").arg(tr("New Sequence")).arg(f->id()));
×
786
                    m_showview->addSequence(sequence, m_currentTrack);
×
787
                    ChaserStep step(m_currentScene->id(), m_currentScene->fadeInSpeed(), 10000, m_currentScene->fadeOutSpeed());
×
788
                    step.note = QString();
×
789
                    step.values.append(m_currentScene->values());
×
790
                    sequence->addStep(step);
×
791
                }
×
792
            }
793
            else if (selectedFunc->type() == Function::ChaserType)
×
794
            {
795
                /** 4.2) add chaser to the new track */
796
                m_showview->addSequence(qobject_cast<Chaser*>(selectedFunc), m_currentTrack);
×
797
            }
798
            else if (selectedFunc->type() == Function::SequenceType)
×
799
            {
800
                /** 3.2) create a new Scene and bind a Sequence clone to it */
801
                Sequence *sequence = qobject_cast<Sequence*>(selectedFunc);
×
802
                Sequence *newSequence = qobject_cast<Sequence*>(sequence->createCopy(m_doc, true));
×
803
                newSequence->setName(sequence->name() + tr(" (Copy)"));
×
804
                newSequence->setDirection(Function::Forward);
×
805
                newSequence->setRunOrder(Function::SingleShot);
×
806
                m_showview->addSequence(newSequence, m_currentTrack);
×
807
            }
808
            else if (selectedFunc->type() == Function::AudioType)
×
809
            {
810
                /** 5.2) add audio to the new track */
811
                Audio *audio = qobject_cast<Audio*> (selectedFunc);
×
812
                m_showview->addAudio(audio, m_currentTrack);
×
813
            }
814
            else if (selectedFunc->type() == Function::RGBMatrixType)
×
815
            {
816
                /** 6.2) add RGBMatrix to the new track */
817
                RGBMatrix *rgbm = qobject_cast<RGBMatrix*> (selectedFunc);
×
818
                m_showview->addRGBMatrix(rgbm, m_currentTrack);
×
819
            }
820
            else if (selectedFunc->type() == Function::EFXType)
×
821
            {
822
                /** 7.2) add EFX to the new track */
823
                EFX *efx = qobject_cast<EFX*> (selectedFunc);
×
824
                m_showview->addEFX(efx, m_currentTrack);
×
825
            }
826
            else if (selectedFunc->type() == Function::VideoType)
×
827
            {
828
                /** 8.2) add video to the new track */
829
                Video *video = qobject_cast<Video*> (selectedFunc);
×
830
                m_showview->addVideo(video, m_currentTrack);
×
831
            }
832
        }
833
        m_doc->setModified();
×
834

835
        m_addSequenceAction->setEnabled(true);
×
836
        m_addAudioAction->setEnabled(true);
×
837
        m_addVideoAction->setEnabled(true);
×
838
        m_showview->activateTrack(m_currentTrack);
×
839
        m_deleteAction->setEnabled(true);
×
840
        m_showview->updateViewSize();
×
841
    }
×
842
}
×
843

844
void ShowManager::slotAddSequence()
×
845
{
846
    // Overlapping check
847
    if (checkOverlapping(m_showview->getTimeFromCursor(), 1000) == true)
×
848
    {
849
        QMessageBox::warning(this, tr("Overlapping error"), tr("Overlapping not allowed. Operation canceled."));
×
850
        return;
×
851
    }
852

853
    if (m_currentTrack->getSceneID() == Function::invalidId())
×
854
    {
855
        m_currentScene = new Scene(m_doc);
×
856
        m_currentScene->setVisible(false);
×
857

858
        if (m_doc->addFunction(m_currentScene))
×
859
            m_currentScene->setName(tr("Scene for %1 - Track %2").arg(m_show->name()).arg(m_currentTrack->id() + 1));
×
860
        m_currentTrack->setSceneID(m_currentScene->id());
×
861
    }
862

863
    Function* f = new Sequence(m_doc);
×
864
    Sequence *sequence = qobject_cast<Sequence*> (f);
×
865
    sequence->setBoundSceneID(m_currentScene->id());
×
866

867
    if (m_doc->addFunction(f) == true)
×
868
    {
869
        sequence->setRunOrder(Function::SingleShot);
×
870
        m_currentScene->setVisible(false);
×
871
        f->setName(QString("%1 %2").arg(tr("New Sequence")).arg(f->id()));
×
872
        showSceneEditor(m_currentScene);
×
873
        showRightEditor(f);
×
874
        m_showview->addSequence(sequence, m_currentTrack);
×
875
    }
876
}
877

878
void ShowManager::slotAddAudio()
×
879
{
880
    QString fn;
×
881

882
    /* Create a file open dialog */
883
    QFileDialog dialog(this);
×
884
    dialog.setWindowTitle(tr("Open Audio File"));
×
885
    dialog.setAcceptMode(QFileDialog::AcceptOpen);
×
886
    //dialog.selectFile(fileName());
887

888
    /* Append file filters to the dialog */
889
    QStringList extList = m_doc->audioPluginCache()->getSupportedFormats();
×
890

891
    QStringList filters;
×
892
    qDebug() << Q_FUNC_INFO << "Extensions: " << extList.join(" ");
×
893
    filters << tr("Audio Files (%1)").arg(extList.join(" "));
×
894
#if defined(WIN32) || defined(Q_OS_WIN)
895
    filters << tr("All Files (*.*)");
896
#else
897
    filters << tr("All Files (*)");
×
898
#endif
899
    dialog.setNameFilters(filters);
×
900

901
    /* Append useful URLs to the dialog */
902
    QList <QUrl> sidebar;
×
903
    sidebar.append(QUrl::fromLocalFile(QDir::homePath()));
×
904
    sidebar.append(QUrl::fromLocalFile(QDir::rootPath()));
×
905
    dialog.setSidebarUrls(sidebar);
×
906

907
    /* Get file name */
908
    if (dialog.exec() != QDialog::Accepted)
×
909
        return;
×
910

911
    fn = dialog.selectedFiles().first();
×
912
    if (fn.isEmpty() == true)
×
913
        return;
×
914

915
    Function* f = new Audio(m_doc);
×
916
    Audio *audio = qobject_cast<Audio*> (f);
×
917
    if (audio->setSourceFileName(fn) == false)
×
918
    {
919
        QMessageBox::warning(this, tr("Unsupported audio file"), tr("This audio file cannot be played with QLC+. Sorry."));
×
920
        delete f;
×
921
        return;
×
922
    }
923
    // Overlapping check
924
    if (checkOverlapping(m_showview->getTimeFromCursor(), audio->totalDuration()) == true)
×
925
    {
926
        QMessageBox::warning(this, tr("Overlapping error"), tr("Overlapping not allowed. Operation canceled."));
×
927
        delete f;
×
928
        return;
×
929
    }
930
    if (m_doc->addFunction(f) == true)
×
931
    {
932
        m_showview->addAudio(audio, m_currentTrack);
×
933
    }
934
}
×
935

936
void ShowManager::slotAddVideo()
×
937
{
938
    QString fn;
×
939

940
    /* Create a file open dialog */
941
    QFileDialog dialog(this);
×
942
    dialog.setWindowTitle(tr("Open Video File"));
×
943
    dialog.setAcceptMode(QFileDialog::AcceptOpen);
×
944
    //dialog.selectFile(fileName());
945

946
    /* Append file filters to the dialog */
947
    QStringList extList = Video::getVideoCapabilities();
×
948

949
    QStringList filters;
×
950
    qDebug() << Q_FUNC_INFO << "Extensions: " << extList.join(" ");
×
951
    filters << tr("Video Files (%1)").arg(extList.join(" "));
×
952
#if defined(WIN32) || defined(Q_OS_WIN)
953
    filters << tr("All Files (*.*)");
954
#else
955
    filters << tr("All Files (*)");
×
956
#endif
957
    dialog.setNameFilters(filters);
×
958

959
    /* Append useful URLs to the dialog */
960
    QList <QUrl> sidebar;
×
961
    sidebar.append(QUrl::fromLocalFile(QDir::homePath()));
×
962
    sidebar.append(QUrl::fromLocalFile(QDir::rootPath()));
×
963
    dialog.setSidebarUrls(sidebar);
×
964

965
    /* Get file name */
966
    if (dialog.exec() != QDialog::Accepted)
×
967
        return;
×
968

969
    fn = dialog.selectedFiles().first();
×
970
    if (fn.isEmpty() == true)
×
971
        return;
×
972

973
    Function* f = new Video(m_doc);
×
974
    Video *video = qobject_cast<Video*> (f);
×
975
    if (video->setSourceUrl(fn) == false)
×
976
    {
977
        QMessageBox::warning(this, tr("Unsupported video file"), tr("This video file cannot be played with QLC+. Sorry."));
×
978
        delete f;
×
979
        return;
×
980
    }
981
    // Overlapping check
982
    if (checkOverlapping(m_showview->getTimeFromCursor(), video->totalDuration()) == true)
×
983
    {
984
        QMessageBox::warning(this, tr("Overlapping error"), tr("Overlapping not allowed. Operation canceled."));
×
985
        delete f;
×
986
        return;
×
987
    }
988
    if (m_doc->addFunction(f) == true)
×
989
    {
990
        m_showview->addVideo(video, m_currentTrack);
×
991
    }
992
}
×
993

994
void ShowManager::slotCopy()
×
995
{
996
    ShowItem *item = m_showview->getSelectedItem();
×
997
    if (item != NULL)
×
998
    {
999
        Function* function = m_doc->function(item->functionID());
×
1000
        Q_ASSERT(function != NULL);
×
1001

1002
        m_doc->clipboard()->copyContent(m_show->id(), function);
×
1003
        m_pasteAction->setEnabled(true);
×
1004
    }
1005
}
×
1006

1007
void ShowManager::slotPaste()
×
1008
{
1009
    if (m_doc->clipboard()->hasFunction() == false)
×
1010
        return;
×
1011

1012
    // Get the Function copy and add it to Doc
1013
    Function* clipboardCopy = m_doc->clipboard()->getFunction();
×
1014
    quint32 copyDuration = clipboardCopy->totalDuration();
×
1015

1016
    // Overlapping check
1017
    if (checkOverlapping(m_showview->getTimeFromCursor(), copyDuration) == true)
×
1018
    {
1019
        QMessageBox::warning(this, tr("Paste error"), tr("Overlapping paste not allowed. Operation canceled."));
×
1020
        return;
×
1021
    }
1022
    //qDebug() << "Check overlap... cursor time:" << cursorTime << "msec";
1023

1024
    if (clipboardCopy != NULL)
×
1025
    {
1026
        // copy the function again, to allow multiple copies of the same function
1027
        Function* newCopy = clipboardCopy->createCopy(m_doc, false);
×
1028
        if (newCopy == NULL)
×
1029
            return;
×
1030

1031
        if (clipboardCopy->type() == Function::ChaserType)
×
1032
        {
1033
            Chaser *chaser = qobject_cast<Chaser*>(newCopy);
×
1034

1035
            if (m_doc->addFunction(newCopy) == false)
×
1036
            {
1037
                delete newCopy;
×
1038
                return;
×
1039
            }
1040
            m_showview->addSequence(chaser, m_currentTrack);
×
1041
        }
1042
        else if (clipboardCopy->type() == Function::SequenceType)
×
1043
        {
1044
            Sequence *sequence = qobject_cast<Sequence*>(newCopy);
×
1045

1046
            if (m_currentScene == NULL)
×
1047
            {
1048
                // No scene on the current track -> copy it from source sequence
1049
                Scene* clipboardCopyScene = qobject_cast<Scene*>(m_doc->function(sequence->boundSceneID()));
×
1050
                if (clipboardCopyScene == NULL)
×
1051
                {
1052
                    delete newCopy;
×
1053
                    return;
×
1054
                }
1055
                Scene* newScene = static_cast<Scene*>(clipboardCopyScene->createCopy(m_doc, true));
×
1056
                if (newScene == NULL)
×
1057
                {
1058
                    delete newCopy;
×
1059
                    return;
×
1060
                }
1061
                m_currentScene = newScene;
×
1062
                m_currentTrack->setSceneID(m_currentScene->id());
×
1063
            }
1064
            else
1065
            {
1066
                // Verify the Chaser copy steps against the current Scene
1067
                foreach (ChaserStep cs, sequence->steps())
×
1068
                {
1069
                    foreach (SceneValue scv, cs.values)
×
1070
                    {
1071
                        if (m_currentScene->checkValue(scv) == false)
×
1072
                        {
1073
                            QMessageBox::warning(this, tr("Paste error"), tr("Trying to paste on an incompatible Scene. Operation canceled."));
×
1074
                            delete newCopy;
×
1075
                            return;
×
1076
                        }
1077
                    }
×
1078
                }
×
1079
            }
1080

1081
            // Bind the sequence to the track Scene ID
1082
            sequence->setBoundSceneID(m_currentScene->id());
×
1083

1084
            if (m_doc->addFunction(newCopy) == false)
×
1085
            {
1086
                delete newCopy;
×
1087
                return;
×
1088
            }
1089
            Track *track = m_currentTrack;
×
1090
            track = m_show->getTrackFromSceneID(m_currentScene->id());
×
1091
            m_showview->addSequence(sequence, track);
×
1092
        }
1093
        else if (clipboardCopy->type() == Function::AudioType)
×
1094
        {
1095
            if (m_doc->addFunction(newCopy) == false)
×
1096
            {
1097
                delete newCopy;
×
1098
                return;
×
1099
            }
1100
            Audio *audio = qobject_cast<Audio*>(newCopy);
×
1101
            m_showview->addAudio(audio, m_currentTrack);
×
1102
        }
1103
        else if (clipboardCopy->type() == Function::RGBMatrixType)
×
1104
        {
1105
            if (m_doc->addFunction(newCopy) == false)
×
1106
            {
1107
                delete newCopy;
×
1108
                return;
×
1109
            }
1110
            RGBMatrix *rgbm = qobject_cast<RGBMatrix*>(newCopy);
×
1111
            m_showview->addRGBMatrix(rgbm, m_currentTrack);
×
1112
        }
1113
        else if (clipboardCopy->type() == Function::EFXType)
×
1114
        {
1115
            if (m_doc->addFunction(newCopy) == false)
×
1116
            {
1117
                delete newCopy;
×
1118
                return;
×
1119
            }
1120
            EFX *efx = qobject_cast<EFX*>(newCopy);
×
1121
            m_showview->addEFX(efx, m_currentTrack);
×
1122
        }
1123
        else if (clipboardCopy->type() == Function::VideoType)
×
1124
        {
1125
            if (m_doc->addFunction(newCopy) == false)
×
1126
            {
1127
                delete newCopy;
×
1128
                return;
×
1129
            }
1130
            Video *video = qobject_cast<Video*>(newCopy);
×
1131
            m_showview->addVideo(video, m_currentTrack);
×
1132
        }
1133
        else if (clipboardCopy->type() == Function::SceneType)
×
1134
        {
1135
            if (m_doc->addFunction(newCopy) == false)
×
1136
            {
1137
                delete newCopy;
×
1138
                return;
×
1139
            }
1140
            m_currentScene = qobject_cast<Scene*>(newCopy);
×
1141
            Track* newTrack = new Track(m_currentScene->id());
×
1142
            newTrack->setName(m_currentScene->name());
×
1143
            m_show->addTrack(newTrack);
×
1144
            //showSceneEditor(m_currentScene);
1145
            m_showview->addTrack(newTrack);
×
1146
            m_addSequenceAction->setEnabled(true);
×
1147
            m_addAudioAction->setEnabled(true);
×
1148
            m_addVideoAction->setEnabled(true);
×
1149
            m_showview->activateTrack(newTrack);
×
1150
            m_deleteAction->setEnabled(true);
×
1151
            m_showview->updateViewSize();
×
1152
        }
1153
    }
1154
}
1155

1156
void ShowManager::slotDelete()
×
1157
{
1158
    // find out if we're deleting a show item or a track
1159
    bool isTrack = true;
×
1160
    ShowItem *selectedItem = m_showview->getSelectedItem();
×
1161
    if (selectedItem != NULL)
×
1162
        isTrack = false;
×
1163

1164
    // get the ID of the function to delete (invalidId if nothing was selected)
1165
    quint32 deleteID = m_showview->deleteSelectedItem();
×
1166
    if (deleteID != Function::invalidId())
×
1167
    {
1168
        if (isTrack == false)
×
1169
        {
1170
            if (m_currentTrack != NULL)
×
1171
            {
1172
                hideRightEditor();
×
1173
                showSceneEditor(NULL);
×
1174
                m_currentTrack->removeShowFunction(selectedItem->showFunction());
×
1175
                m_doc->setModified();
×
1176
            }
1177
        }
1178
        else
1179
        {
1180
            m_show->removeTrack(deleteID);
×
1181
            m_doc->setModified();
×
1182
            updateMultiTrackView();
×
1183
        }
1184
    }
1185
}
×
1186

1187
void ShowManager::slotStopPlayback()
×
1188
{
1189
    m_playAction->setIcon(QIcon(":/player_play.png"));
×
1190
    if (m_show != NULL && m_show->isRunning())
×
1191
    {
1192
        m_show->stop(functionParent());
×
1193
        return;
×
1194
    }
1195
    m_showview->rewindCursor();
×
1196
    m_timeLabel->setText("00:00:00.00");
×
1197
}
1198

1199
void ShowManager::slotStartPlayback()
×
1200
{
1201
    if (m_showsCombo->count() == 0 || m_show == NULL)
×
1202
        return;
×
1203

1204
    if (m_show->isRunning() == false)
×
1205
    {
1206
        cursorMovedDuringPause = false;
×
1207
        m_show->start(m_doc->masterTimer(), functionParent(), m_showview->getTimeFromCursor());
×
1208
        m_playAction->setIcon(QIcon(":/player_pause.png"));
×
1209
    }
1210
    else
1211
    {
1212
        if (m_show->isPaused())
×
1213
        {
1214
            m_playAction->setIcon(QIcon(":/player_pause.png"));
×
1215
            if (cursorMovedDuringPause)
×
1216
            {
1217
                m_show->stop(functionParent());
×
1218
                m_show->stopAndWait();
×
1219
                cursorMovedDuringPause = false;
×
1220
                m_show->start(m_doc->masterTimer(), functionParent(), m_showview->getTimeFromCursor());
×
1221
            }
1222
            else
1223
            {
1224
                m_show->setPause(false);
×
1225
            }
1226
        }
1227
        else
1228
        {
1229
            m_playAction->setIcon(QIcon(":/player_play.png"));
×
1230
            m_show->setPause(true);
×
1231
        }
1232
    }
1233
}
1234

1235
void ShowManager::slotShowStopped()
×
1236
{
1237
    slotUpdateTime(m_showview->getTimeFromCursor());
×
1238
}
×
1239

1240
void ShowManager::slotTimeDivisionTypeChanged(int idx)
×
1241
{
1242
    QVariant var = m_timeDivisionCombo->itemData(idx);
×
1243
    if (var.isValid())
×
1244
    {
1245
        m_showview->setHeaderType((Show::TimeDivision)var.toInt());
×
1246
        if (idx > 0)
×
1247
            m_bpmField->setEnabled(true);
×
1248
        else
1249
            m_bpmField->setEnabled(false);
×
1250
        if (m_show != NULL)
×
1251
            m_show->setTimeDivision((Show::TimeDivision)var.toInt(), m_bpmField->value());
×
1252
    }
1253
}
×
1254

1255
void ShowManager::slotBPMValueChanged(int value)
×
1256
{
1257
    m_showview->setBPMValue(value);
×
1258
    QVariant var = m_timeDivisionCombo->itemData(m_timeDivisionCombo->currentIndex());
×
1259
    if (var.isValid() && m_show != NULL)
×
1260
        m_show->setTimeDivision((Show::TimeDivision)var.toInt(), m_bpmField->value());
×
1261
}
×
1262

1263
void ShowManager::slotViewClicked(QMouseEvent *event)
×
1264
{
1265
    Q_UNUSED(event)
1266
    //qDebug() << Q_FUNC_INFO << "View clicked at pos: " << event->pos().x() << event->pos().y();
1267
    showSceneEditor(NULL);
×
1268
    hideRightEditor();
×
1269
    m_colorAction->setEnabled(false);
×
1270
    m_lockAction->setIcon(QIcon(":/lock.png"));
×
1271
    m_lockAction->setEnabled(false);
×
1272
    m_timingsAction->setEnabled(false);
×
1273
    if (m_show != NULL && m_show->getTracksCount() == 0)
×
1274
        m_deleteAction->setEnabled(false);
×
1275
}
×
1276

1277
void ShowManager::slotShowItemMoved(ShowItem *item, quint32 time, bool moved)
×
1278
{
1279
    if (item == NULL)
×
1280
        return;
×
1281

1282
    quint32 fid = item->functionID();
×
1283
    Function *f = m_doc->function(fid);
×
1284
    if (f == NULL)
×
1285
        return;
×
1286

1287
    Sequence *sequence = NULL;
×
1288

1289
    if (f->type() == Function::SequenceType)
×
1290
        sequence = qobject_cast<Sequence*>(f);
×
1291

1292
    if (sequence != NULL)
×
1293
    {
1294
        quint32 sceneID = sequence->boundSceneID();
×
1295
        Function *sf = m_doc->function(sceneID);
×
1296

1297
        if (sf == NULL)
×
1298
        {
1299
            // The bound Scene no longer exists. Invalidate the Sequence
1300
            sequence->setBoundSceneID(Function::invalidId());
×
1301
        }
1302
        else
1303
        {
1304
            Scene *boundScene = qobject_cast<Scene*>(sf);
×
1305

1306
            // if the clicked item represents another Sequence,
1307
            // destroy the Scene editor cause they might share
1308
            // the same bound Scene and Scene values might be overwritten
1309
            if (fid != m_editorFunctionID)
×
1310
                showSceneEditor(NULL);
×
1311

1312
            if (boundScene != m_currentScene || m_sceneEditor == NULL)
×
1313
            {
1314
                m_currentScene = boundScene;
×
1315
                showSceneEditor(m_currentScene);
×
1316
            }
1317

1318
            /* activate the new track */
1319
            m_currentTrack = m_show->getTrackFromSceneID(sceneID);
×
1320
            m_showview->activateTrack(m_currentTrack);
×
1321
            showRightEditor(f);
×
1322

1323
            if (m_currentEditor != NULL)
×
1324
            {
1325
                ChaserEditor *editor = qobject_cast<ChaserEditor*>(m_currentEditor);
×
1326
                editor->selectStepAtTime(time - item->getStartTime());
×
1327
            }
1328
        }
1329
    }
1330
    else
1331
    {
1332
        Track *track = m_show->tracks().at(item->getTrackIndex());
×
1333
        m_showview->activateTrack(track);
×
1334
        m_currentTrack = track;
×
1335
        m_currentScene = NULL;
×
1336
        showSceneEditor(NULL);
×
1337
        showRightEditor(f);
×
1338
    }
1339

1340
    m_copyAction->setEnabled(true);
×
1341
    m_deleteAction->setEnabled(true);
×
1342
    m_colorAction->setEnabled(true);
×
1343
    m_lockAction->setEnabled(true);
×
1344
    if (item->isLocked() == false)
×
1345
        m_lockAction->setIcon(QIcon(":/lock.png"));
×
1346
    else
1347
        m_lockAction->setIcon(QIcon(":/unlock.png"));
×
1348
    m_timingsAction->setEnabled(true);
×
1349

1350
    if (moved == true)
×
1351
        m_doc->setModified();
×
1352
}
1353

1354
void ShowManager::slotUpdateTimeAndCursor(quint32 msec_time)
×
1355
{
1356
    //qDebug() << Q_FUNC_INFO << "time: " << msec_time;
1357
    slotUpdateTime(msec_time);
×
1358
    m_showview->moveCursor(msec_time);
×
1359
}
×
1360

1361
void ShowManager::slotUpdateTime(quint32 msec_time)
×
1362
{
1363
    uint h, m, s;
1364

1365
    h = msec_time / MS_PER_HOUR;
×
1366
    msec_time -= (h * MS_PER_HOUR);
×
1367

1368
    m = msec_time / MS_PER_MINUTE;
×
1369
    msec_time -= (m * MS_PER_MINUTE);
×
1370

1371
    s = msec_time / MS_PER_SECOND;
×
1372
    msec_time -= (s * MS_PER_SECOND);
×
1373

1374
    QString str;
×
1375
    if (m_show && m_show->isRunning())
×
1376
    {
1377
        str = QString("%1:%2:%3.%4").arg(h, 2, 10, QChar('0')).arg(m, 2, 10, QChar('0'))
×
1378
              .arg(s, 2, 10, QChar('0')).arg(msec_time / 100, 1, 10, QChar('0'));
×
1379
    }
1380
    else
1381
        str = QString("%1:%2:%3.%4").arg(h, 2, 10, QChar('0')).arg(m, 2, 10, QChar('0'))
×
1382
              .arg(s, 2, 10, QChar('0')).arg(msec_time / 10, 2, 10, QChar('0'));
×
1383

1384
    m_timeLabel->setText(str);
×
1385

1386
    if (m_show != NULL && m_show->isPaused())
×
1387
        cursorMovedDuringPause = true;
×
1388
}
×
1389

1390
void ShowManager::slotTrackClicked(Track *track)
×
1391
{
1392
    m_currentTrack = track;
×
1393
    if (track->getSceneID() == Function::invalidId())
×
1394
        m_currentScene = NULL;
×
1395
    else
1396
    {
1397
        Function *f = m_doc->function(track->getSceneID());
×
1398
        if (f != NULL)
×
1399
            m_currentScene = qobject_cast<Scene*>(f);
×
1400
    }
1401
    m_deleteAction->setEnabled(true);
×
1402
    m_copyAction->setEnabled(true);
×
1403
}
×
1404

1405
void ShowManager::slotTrackDoubleClicked(Track *track)
×
1406
{
1407
    bool ok;
1408
    QString currentName = track->name();
×
1409
    QString newTrackName = QInputDialog::getText(this, tr("Track name setup"),
×
1410
                                         tr("Track name:"), QLineEdit::Normal,
×
1411
                                         currentName, &ok);
×
1412

1413
    if (ok == true && newTrackName.isEmpty() == false)
×
1414
    {
1415
        track->setName(newTrackName);
×
1416
        int idx = m_show->getAttributeIndex(track->name());
×
1417
        m_show->renameAttribute(idx, track->name());
×
1418
    }
1419
}
×
1420

1421
void ShowManager::slotTrackMoved(Track *track, int direction)
×
1422
{
1423
    if (m_show != NULL)
×
1424
        m_show->moveTrack(track, direction);
×
1425
    updateMultiTrackView();
×
1426
    m_doc->setModified();
×
1427
}
×
1428

1429
void ShowManager::slotTrackDelete(Track *track)
×
1430
{
1431
    if (track == NULL)
×
1432
        return;
×
1433

1434
    quint32 deleteID = m_showview->deleteSelectedItem();
×
1435
    if (deleteID != Function::invalidId())
×
1436
    {
1437
        m_show->removeTrack(deleteID);
×
1438
        m_doc->setModified();
×
1439
        updateMultiTrackView();
×
1440
    }
1441
}
1442

1443
void ShowManager::slotChangeColor()
×
1444
{
1445
    ShowItem *item = m_showview->getSelectedItem();
×
1446
    if (item != NULL)
×
1447
    {
1448
        QColor color = item->getColor();
×
1449

1450
        color = QColorDialog::getColor(color);
×
1451
        if (!color.isValid())
×
1452
            return;
×
1453
        item->setColor(color);
×
1454
        return;
×
1455
    }
1456
}
1457

1458
void ShowManager::slotChangeLock()
×
1459
{
1460
    ShowItem *item = m_showview->getSelectedItem();
×
1461
    if (item != NULL)
×
1462
    {
1463
        if (item->isLocked() == false)
×
1464
            m_lockAction->setIcon(QIcon(":/unlock.png"));
×
1465
        else
1466
            m_lockAction->setIcon(QIcon(":/lock.png"));
×
1467
        item->setLocked(!item->isLocked());
×
1468
    }
1469
}
×
1470

1471
void ShowManager::slotShowTimingsTool()
×
1472
{
1473
    ShowItem *item = m_showview->getSelectedItem();
×
1474

1475
    if (item == NULL)
×
1476
        return;
×
1477

1478
    TimingsTool *tt = new TimingsTool(item, this);
×
1479

1480
    Function *func = m_doc->function(item->functionID());
×
1481
    if (func != NULL)
×
1482
    {
1483
        if (func->type() == Function::AudioType)
×
1484
            tt->showDurationControls(false);
×
1485
        if (func->type() == Function::RGBMatrixType || func->type() == Function::EFXType)
×
1486
            tt->showDurationOptions(true);
×
1487
    }
1488

1489
    connect(tt, SIGNAL(startTimeChanged(ShowItem*,int)),
×
1490
            this, SLOT(slotShowItemStartTimeChanged(ShowItem*,int)));
1491
    connect(tt, SIGNAL(durationChanged(ShowItem*,int,bool)),
×
1492
            this, SLOT(slotShowItemDurationChanged(ShowItem*,int,bool)));
1493
    tt->show();
×
1494
}
1495

1496
void ShowManager::slotShowItemStartTimeChanged(ShowItem *item, int msec)
×
1497
{
1498
    if (item == NULL)
×
1499
        return;
×
1500

1501
    if (item->isLocked() == false)
×
1502
    {
1503
        item->setStartTime(msec);
×
1504
        item->setPos(m_showview->getPositionFromTime(msec), item->y());
×
1505
        m_doc->setModified();
×
1506
    }
1507
}
1508

1509
void ShowManager::slotShowItemDurationChanged(ShowItem *item, int msec, bool stretch)
×
1510
{
1511
    if (item == NULL)
×
1512
        return;
×
1513

1514
    item->setDuration(msec, stretch);
×
1515
    m_doc->setModified();
×
1516
}
1517

1518
void ShowManager::slotToggleSnapToGrid(bool enable)
×
1519
{
1520
    m_showview->setSnapToGrid(enable);
×
1521
}
×
1522

1523
void ShowManager::slotChangeSize(int width, int height)
×
1524
{
1525
    if (m_showview != NULL)
×
1526
        m_showview->setViewSize(width, height);
×
1527
}
×
1528

1529
void ShowManager::slotStepSelectionChanged(int index)
×
1530
{
1531
    SequenceItem *seqItem = qobject_cast<SequenceItem*>(m_showview->getSelectedItem());
×
1532
    if (seqItem != NULL)
×
1533
        seqItem->setSelectedStep(index);
×
1534
}
×
1535

1536
void ShowManager::slotDocClearing()
×
1537
{
1538
    m_showsCombo->clear();
×
1539

1540
    if (m_showview != NULL)
×
1541
        m_showview->resetView();
×
1542

1543
    if (m_currentEditor != NULL)
×
1544
    {
1545
        m_vsplitter->widget(1)->layout()->removeWidget(m_currentEditor);
×
1546
        delete m_currentEditor;
×
1547
        m_currentEditor = NULL;
×
1548
    }
1549
    m_vsplitter->widget(1)->hide();
×
1550

1551
    if (m_sceneEditor != NULL)
×
1552
    {
1553
        emit functionManagerActive(false);
×
1554
        m_splitter->widget(1)->layout()->removeWidget(m_sceneEditor);
×
1555
        delete m_sceneEditor;
×
1556
        m_sceneEditor = NULL;
×
1557
    }
1558
    m_splitter->widget(1)->hide();
×
1559

1560
    m_addTrackAction->setEnabled(false);
×
1561
    m_addSequenceAction->setEnabled(false);
×
1562
    m_addAudioAction->setEnabled(false);
×
1563
    m_addVideoAction->setEnabled(false);
×
1564
    m_copyAction->setEnabled(false);
×
1565
    m_deleteAction->setEnabled(false);
×
1566
    m_colorAction->setEnabled(false);
×
1567
    m_timeLabel->setText("00:00:00.00");
×
1568
}
×
1569

1570
void ShowManager::slotDocLoaded()
×
1571
{
1572
    m_show = NULL;
×
1573
    m_currentScene = NULL;
×
1574
    m_currentTrack = NULL;
×
1575
    updateShowsCombo();
×
1576
}
×
1577

1578
void ShowManager::slotFunctionRemoved(quint32 id)
×
1579
{
1580
    if (m_showsCombo->count() == 0)
×
1581
        return;
×
1582

1583
    // check if ID is a Show
1584
    for (int i = 0; i < m_showsCombo->count(); i++)
×
1585
    {
1586
        quint32 showID = m_showsCombo->itemData(i).toUInt();
×
1587
        if (showID == id)
×
1588
        {
1589
            m_showsCombo->blockSignals(true);
×
1590
            m_showsCombo->removeItem(i);
×
1591

1592
            if (i == m_selectedShowIndex)
×
1593
            {
1594
                m_show = NULL;
×
1595
                m_selectedShowIndex = -1;
×
1596
                updateMultiTrackView();
×
1597
            }
1598
            m_showsCombo->blockSignals(false);
×
1599
            return;
×
1600
        }
1601
    }
1602

1603
    foreach (Function *function, m_doc->functionsByType(Function::ShowType))
×
1604
    {
1605
        Show *show = qobject_cast<Show*>(function);
×
1606
        foreach (Track *track, show->tracks())
×
1607
        {
1608
            foreach (ShowFunction *sf, track->showFunctions())
×
1609
            {
1610
                if (sf->functionID() == id)
×
1611
                    m_showview->deleteShowItem(track, sf);
×
1612
            }
×
1613

1614
            // check if the Function being removed is a Scene bound to a Track
1615
            if (track->getSceneID() == id)
×
1616
                track->setSceneID(Function::invalidId());
×
1617
        }
×
1618
    }
×
1619

1620
    if (m_currentScene != NULL && m_currentScene->id() == id)
×
1621
        m_currentScene = NULL;
×
1622

1623
    //if (isVisible())
1624
    //    updateMultiTrackView();
1625
}
1626

1627
void ShowManager::updateMultiTrackView()
×
1628
{
1629
    qDebug() << "[ShowManager] updateMultiTrackView...";
×
1630
    m_showview->resetView();
×
1631

1632
    /* first of all get the ID of the selected Show */
1633
    int idx = m_showsCombo->currentIndex();
×
1634
    if (idx == -1)
×
1635
        return;
×
1636
    quint32 showID = m_showsCombo->itemData(idx).toUInt();
×
1637

1638
    m_show = qobject_cast<Show *>(m_doc->function(showID));
×
1639
    if (m_show == NULL)
×
1640
    {
1641
        qDebug() << Q_FUNC_INFO << "Invalid show!";
×
1642
        return;
×
1643
    }
1644

1645
    // disconnect BPM field and update the view manually, to
1646
    // prevent m_show time division override
1647
    disconnect(m_bpmField, SIGNAL(valueChanged(int)), this, SLOT(slotBPMValueChanged(int)));
×
1648

1649
    m_bpmField->setValue(m_show->timeDivisionBPM());
×
1650
    m_showview->setBPMValue(m_show->timeDivisionBPM());
×
1651
    int tIdx = m_timeDivisionCombo->findData(QVariant(m_show->timeDivisionType()));
×
1652
    m_timeDivisionCombo->setCurrentIndex(tIdx);
×
1653

1654
    connect(m_bpmField, SIGNAL(valueChanged(int)), this, SLOT(slotBPMValueChanged(int)));
×
1655
    connect(m_show, SIGNAL(timeChanged(quint32)), this, SLOT(slotUpdateTimeAndCursor(quint32)));
×
1656
    connect(m_show, SIGNAL(showFinished()), this, SLOT(slotStopPlayback()));
×
1657
    connect(m_show, SIGNAL(stopped(quint32)), this, SLOT(slotShowStopped()));
×
1658

1659
    Track *firstTrack = NULL;
×
1660

1661
    foreach (Track *track, m_show->tracks())
×
1662
    {
1663
        if (firstTrack == NULL)
×
1664
            firstTrack = track;
×
1665

1666
        quint32 boundSceneID = track->getSceneID();
×
1667
        if (boundSceneID != Function::invalidId())
×
1668
        {
1669
            Function *f = m_doc->function(boundSceneID);
×
1670
            if (f == NULL || f->type() != Function::SceneType)
×
1671
                track->setSceneID(Function::invalidId());
×
1672
        }
1673

1674
        m_showview->addTrack(track);
×
1675

1676
        foreach (ShowFunction *sf, track->showFunctions())
×
1677
        {
1678
            Function *fn = m_doc->function(sf->functionID());
×
1679
            if (fn != NULL)
×
1680
            {
1681
                if (fn->type() == Function::ChaserType)
×
1682
                {
1683
                    Chaser *chaser = qobject_cast<Chaser*>(fn);
×
1684
                    m_showview->addSequence(chaser, track, sf);
×
1685
                }
1686
                else if (fn->type() == Function::SequenceType)
×
1687
                {
1688
                    Sequence *sequence = qobject_cast<Sequence*>(fn);
×
1689
                    m_showview->addSequence(sequence, track, sf);
×
1690
                }
1691
                else if (fn->type() == Function::AudioType)
×
1692
                {
1693
                    Audio *audio = qobject_cast<Audio*>(fn);
×
1694
                    m_showview->addAudio(audio, track, sf);
×
1695
                }
1696
                else if (fn->type() == Function::RGBMatrixType)
×
1697
                {
1698
                    RGBMatrix *rgbm = qobject_cast<RGBMatrix*>(fn);
×
1699
                    m_showview->addRGBMatrix(rgbm, track, sf);
×
1700
                }
1701
                else if (fn->type() == Function::EFXType)
×
1702
                {
1703
                    EFX *efx = qobject_cast<EFX*>(fn);
×
1704
                    m_showview->addEFX(efx, track, sf);
×
1705
                }
1706
                else if (fn->type() == Function::VideoType)
×
1707
                {
1708
                    Video *video = qobject_cast<Video*>(fn);
×
1709
                    m_showview->addVideo(video, track, sf);
×
1710
                }
1711
            }
1712
        }
×
1713
    }
×
1714
    /** Set first track active */
1715
    if (firstTrack != NULL)
×
1716
    {
1717
        m_currentTrack = firstTrack;
×
1718
        if (m_currentTrack->getSceneID() != Function::invalidId())
×
1719
            m_currentScene = qobject_cast<Scene*>(m_doc->function(m_currentTrack->getSceneID()));
×
1720
        m_showview->activateTrack(m_currentTrack);
×
1721
        m_copyAction->setEnabled(true);
×
1722
        m_addSequenceAction->setEnabled(true);
×
1723
        m_addAudioAction->setEnabled(true);
×
1724
        m_addVideoAction->setEnabled(true);
×
1725
    }
1726
    else
1727
    {
1728
        m_addSequenceAction->setEnabled(false);
×
1729
        m_addAudioAction->setEnabled(false);
×
1730
        m_addVideoAction->setEnabled(false);
×
1731
        m_currentScene = NULL;
×
1732
        showSceneEditor(NULL);
×
1733
    }
1734
    if (m_doc->clipboard()->hasFunction())
×
1735
        m_pasteAction->setEnabled(true);
×
1736
    m_showview->updateViewSize();
×
1737
}
1738

1739
bool ShowManager::checkOverlapping(quint32 startTime, quint32 duration)
×
1740
{
1741
    if (m_currentTrack == NULL)
×
1742
        return false;
×
1743

1744
    foreach (ShowFunction *sf, m_currentTrack->showFunctions())
×
1745
    {
1746
        Function *func = m_doc->function(sf->functionID());
×
1747
        if (func != NULL)
×
1748
        {
1749
            quint32 fst = sf->startTime();
×
1750
            if ((startTime >= fst && startTime <= fst + sf->duration()) ||
×
1751
                (fst >= startTime && fst <= startTime + duration))
×
1752
            {
1753
                return true;
×
1754
            }
1755
        }
1756
    }
×
1757

1758
    return false;
×
1759
}
1760

1761
void ShowManager::showEvent(QShowEvent* ev)
×
1762
{
1763
    qDebug() << Q_FUNC_INFO;
×
1764
    emit functionManagerActive(true);
×
1765
    QWidget::showEvent(ev);
×
1766
    m_showview->show();
×
1767
    m_showview->horizontalScrollBar()->setSliderPosition(0);
×
1768
    m_showview->verticalScrollBar()->setSliderPosition(0);
×
1769
    updateShowsCombo();
×
1770
}
×
1771

1772
void ShowManager::hideEvent(QHideEvent* ev)
×
1773
{
1774
    qDebug() << Q_FUNC_INFO;
×
1775
    emit functionManagerActive(false);
×
1776
    QWidget::hideEvent(ev);
×
1777

1778
    if (m_currentEditor != NULL)
×
1779
    {
1780
        m_vsplitter->widget(1)->layout()->removeWidget(m_currentEditor);
×
1781
        m_vsplitter->widget(1)->hide();
×
1782
        delete m_currentEditor;
×
1783
        m_currentEditor = NULL;
×
1784
        m_editorFunctionID = Function::invalidId();
×
1785
    }
1786

1787
    if (m_sceneEditor != NULL)
×
1788
    {
1789
        m_splitter->widget(1)->layout()->removeWidget(m_sceneEditor);
×
1790
        m_splitter->widget(1)->hide();
×
1791
        delete m_sceneEditor;
×
1792
        m_sceneEditor = NULL;
×
1793
    }
1794

1795
    ShowItem *item = m_showview->getSelectedItem();
×
1796
    if (item != NULL)
×
1797
        item->setSelected(false);
×
1798
}
×
1799

1800
FunctionParent ShowManager::functionParent() const
×
1801
{
1802
    return FunctionParent::master();
×
1803
}
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