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

mcallegari / qlcplus / 6628997562

24 Oct 2023 03:21PM UTC coverage: 28.085% (+0.05%) from 28.038%
6628997562

Pull #1462

github

web-flow
Merge 231f6a87e into 646f68840
Pull Request #1462: Overriding flash functionality

91 of 91 new or added lines in 9 files covered. (100.0%)

15382 of 54770 relevant lines covered (28.08%)

20312.39 hits per line

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

44.6
/ui/src/virtualconsole/virtualconsole.cpp
1
/*
2
  Q Light Controller Plus
3
  virtualconsole.cpp
4

5
  Copyright (c) Heikki Junnila
6
                Massimo Callegari
7

8
  Licensed under the Apache License, Version 2.0 (the "License");
9
  you may not use this file except in compliance with the License.
10
  You may obtain a copy of the License at
11

12
      http://www.apache.org/licenses/LICENSE-2.0.txt
13

14
  Unless required by applicable law or agreed to in writing, software
15
  distributed under the License is distributed on an "AS IS" BASIS,
16
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17
  See the License for the specific language governing permissions and
18
  limitations under the License.
19
*/
20

21
#include <QXmlStreamReader>
22
#include <QXmlStreamWriter>
23
#include <QApplication>
24
#include <QInputDialog>
25
#include <QColorDialog>
26
#include <QActionGroup>
27
#include <QHBoxLayout>
28
#include <QVBoxLayout>
29
#include <QMessageBox>
30
#include <QFileDialog>
31
#include <QFontDialog>
32
#include <QScrollArea>
33
#include <QSettings>
34
#include <QKeyEvent>
35
#include <QMenuBar>
36
#include <QToolBar>
37
#include <QString>
38
#include <QDebug>
39
#include <QMenu>
40
#include <QList>
41

42
#include "vcpropertieseditor.h"
43
#include "addvcbuttonmatrix.h"
44
#include "addvcslidermatrix.h"
45
#include "vcaudiotriggers.h"
46
#include "virtualconsole.h"
47
#include "vcproperties.h"
48
#include "vcspeeddial.h"
49
#include "vcsoloframe.h"
50
#include "vcdockarea.h"
51
#include "vccuelist.h"
52
#include "vcbutton.h"
53
#include "vcslider.h"
54
#include "vcmatrix.h"
55
#include "vcframe.h"
56
#include "vclabel.h"
57
#include "vcxypad.h"
58
#include "vcclock.h"
59
#include "doc.h"
60

61
#define SETTINGS_VC_SIZE "virtualconsole/size"
62

63
VirtualConsole* VirtualConsole::s_instance = NULL;
64

65
/****************************************************************************
66
 * Initialization
67
 ****************************************************************************/
68

69
VirtualConsole::VirtualConsole(QWidget* parent, Doc* doc)
76✔
70
    : QWidget(parent)
71
    , m_doc(doc)
72
    , m_latestWidgetId(0)
73

74
    , m_editAction(EditNone)
75
    , m_toolbar(NULL)
76

77
    , m_addActionGroup(NULL)
78
    , m_editActionGroup(NULL)
79
    , m_bgActionGroup(NULL)
80
    , m_fgActionGroup(NULL)
81
    , m_fontActionGroup(NULL)
82
    , m_frameActionGroup(NULL)
83
    , m_stackingActionGroup(NULL)
84

85
    , m_addButtonAction(NULL)
86
    , m_addButtonMatrixAction(NULL)
87
    , m_addSliderAction(NULL)
88
    , m_addSliderMatrixAction(NULL)
89
    , m_addKnobAction(NULL)
90
    , m_addSpeedDialAction(NULL)
91
    , m_addXYPadAction(NULL)
92
    , m_addCueListAction(NULL)
93
    , m_addFrameAction(NULL)
94
    , m_addSoloFrameAction(NULL)
95
    , m_addLabelAction(NULL)
96
    , m_addAudioTriggersAction(NULL)
97
    , m_addClockAction(NULL)
98
    , m_addAnimationAction(NULL)
99

100
    , m_toolsSettingsAction(NULL)
101

102
    , m_editCutAction(NULL)
103
    , m_editCopyAction(NULL)
104
    , m_editPasteAction(NULL)
105
    , m_editDeleteAction(NULL)
106
    , m_editPropertiesAction(NULL)
107
    , m_editRenameAction(NULL)
108

109
    , m_bgColorAction(NULL)
110
    , m_bgImageAction(NULL)
111
    , m_bgDefaultAction(NULL)
112

113
    , m_fgColorAction(NULL)
114
    , m_fgDefaultAction(NULL)
115

116
    , m_fontAction(NULL)
117
    , m_resetFontAction(NULL)
118

119
    , m_frameSunkenAction(NULL)
120
    , m_frameRaisedAction(NULL)
121
    , m_frameNoneAction(NULL)
122

123
    , m_stackingRaiseAction(NULL)
124
    , m_stackingLowerAction(NULL)
125

126
    , m_customMenu(NULL)
127
    , m_editMenu(NULL)
128
    , m_addMenu(NULL)
129

130
    , m_dockArea(NULL)
131
    , m_contentsLayout(NULL)
132
    , m_scrollArea(NULL)
133
    , m_contents(NULL)
134

135
    , m_liveEdit(false)
76✔
136
{
137
    Q_ASSERT(s_instance == NULL);
76✔
138
    s_instance = this;
76✔
139

140
    Q_ASSERT(doc != NULL);
76✔
141

142
    /* Main layout */
143
    new QHBoxLayout(this);
76✔
144
    layout()->setContentsMargins(1, 1, 1, 1);
76✔
145
    layout()->setSpacing(1);
76✔
146

147
    initActions();
76✔
148
    initDockArea();
76✔
149
    m_contentsLayout = new QVBoxLayout;
76✔
150
    layout()->addItem(m_contentsLayout);
76✔
151
    initMenuBar();
76✔
152
    initContents();
76✔
153

154
    // Propagate mode changes to all widgets
155
    connect(m_doc, SIGNAL(modeChanged(Doc::Mode)),
76✔
156
            this, SLOT(slotModeChanged(Doc::Mode)));
157

158
    // Use the initial mode
159
    slotModeChanged(m_doc->mode());
76✔
160

161
    // Nothing is selected
162
    updateActions();
76✔
163
}
76✔
164

165
VirtualConsole::~VirtualConsole()
152✔
166
{
167
    s_instance = NULL;
76✔
168
}
152✔
169

170
VirtualConsole* VirtualConsole::instance()
822✔
171
{
172
    return s_instance;
822✔
173
}
174

175
Doc *VirtualConsole::getDoc()
×
176
{
177
    return m_doc;
×
178
}
179

180
quint32 VirtualConsole::newWidgetId()
1✔
181
{
182
    /* This results in an endless loop if there are UINT_MAX-1 widgets. That,
183
       however, seems a bit unlikely. */
184
    while (m_widgetsMap.contains(m_latestWidgetId) ||
2✔
185
           m_latestWidgetId == VCWidget::invalidId())
1✔
186
    {
187
        m_latestWidgetId++;
×
188
    }
189

190
    return m_latestWidgetId;
1✔
191
}
192

193
/*****************************************************************************
194
 * Properties
195
 *****************************************************************************/
196

197
VCProperties VirtualConsole::properties() const
154✔
198
{
199
    return m_properties;
154✔
200
}
201

202
/*****************************************************************************
203
 * Selected widget
204
 *****************************************************************************/
205

206
void VirtualConsole::setEditAction(VirtualConsole::EditAction action)
×
207
{
208
    m_editAction = action;
×
209
}
×
210

211
VirtualConsole::EditAction VirtualConsole::editAction() const
×
212
{
213
    return m_editAction;
×
214
}
215

216
const QList <VCWidget*> VirtualConsole::selectedWidgets() const
5✔
217
{
218
    return m_selectedWidgets;
5✔
219
}
220

221
void VirtualConsole::setWidgetSelected(VCWidget* widget, bool select)
4✔
222
{
223
    Q_ASSERT(widget != NULL);
4✔
224

225
    if (select == false)
4✔
226
    {
227
        m_selectedWidgets.removeAll(widget);
×
228
        widget->update();
×
229
    }
230
    else if (select == true && m_selectedWidgets.indexOf(widget) == -1)
4✔
231
    {
232
        m_selectedWidgets.append(widget);
4✔
233
        widget->update();
4✔
234
    }
235

236
    /* Change the custom menu to the latest-selected widget's menu */
237
    updateCustomMenu();
4✔
238

239
    /* Enable or disable actions */
240
    updateActions();
4✔
241
}
4✔
242

243
bool VirtualConsole::isWidgetSelected(VCWidget* widget) const
31✔
244
{
245
    if (widget == NULL || m_selectedWidgets.indexOf(widget) == -1)
31✔
246
        return false;
27✔
247
    else
248
        return true;
4✔
249
}
250

251
void VirtualConsole::clearWidgetSelection()
6✔
252
{
253
    /* Get a copy of selected widget list */
254
    QList <VCWidget*> widgets(m_selectedWidgets);
12✔
255

256
    /* Clear the list so isWidgetSelected() returns false for all widgets */
257
    m_selectedWidgets.clear();
6✔
258

259
    /* Update all widgets to clear the selection frame around them */
260
    QListIterator <VCWidget*> it(widgets);
12✔
261
    while (it.hasNext() == true)
7✔
262
        it.next()->update();
1✔
263

264
    /* Change the custom menu to the latest-selected widget's menu */
265
    updateCustomMenu();
6✔
266

267
    /* Enable or disable actions */
268
    updateActions();
6✔
269
}
6✔
270

271
void VirtualConsole::reselectWidgets()
×
272
{
273
    QList <VCWidget*> widgets(m_selectedWidgets);
×
274
    clearWidgetSelection();
×
275
    foreach (VCWidget* w, widgets)
×
276
        setWidgetSelected(w, true);
×
277
}
×
278

279
/*****************************************************************************
280
 * Actions, menu- and toolbar
281
 *****************************************************************************/
282

283
QMenu* VirtualConsole::customMenu() const
×
284
{
285
    return m_customMenu;
×
286
}
287

288
QMenu* VirtualConsole::editMenu() const
×
289
{
290
    return m_editMenu;
×
291
}
292

293
QMenu* VirtualConsole::addMenu() const
8✔
294
{
295
    return m_addMenu;
8✔
296
}
297

298
void VirtualConsole::initActions()
76✔
299
{
300
    /* Add menu actions */
301
    m_addButtonAction = new QAction(QIcon(":/button.png"), tr("New Button"), this);
76✔
302
    connect(m_addButtonAction, SIGNAL(triggered(bool)), this, SLOT(slotAddButton()), Qt::QueuedConnection);
76✔
303

304
    m_addButtonMatrixAction = new QAction(QIcon(":/buttonmatrix.png"), tr("New Button Matrix"), this);
76✔
305
    connect(m_addButtonMatrixAction, SIGNAL(triggered(bool)), this, SLOT(slotAddButtonMatrix()), Qt::QueuedConnection);
76✔
306

307
    m_addSliderAction = new QAction(QIcon(":/slider.png"), tr("New Slider"), this);
76✔
308
    connect(m_addSliderAction, SIGNAL(triggered(bool)), this, SLOT(slotAddSlider()), Qt::QueuedConnection);
76✔
309

310
    m_addSliderMatrixAction = new QAction(QIcon(":/slidermatrix.png"), tr("New Slider Matrix"), this);
76✔
311
    connect(m_addSliderMatrixAction, SIGNAL(triggered(bool)), this, SLOT(slotAddSliderMatrix()), Qt::QueuedConnection);
76✔
312

313
    m_addKnobAction = new QAction(QIcon(":/knob.png"), tr("New Knob"), this);
76✔
314
    connect(m_addKnobAction, SIGNAL(triggered(bool)), this, SLOT(slotAddKnob()), Qt::QueuedConnection);
76✔
315

316
    m_addSpeedDialAction = new QAction(QIcon(":/speed.png"), tr("New Speed Dial"), this);
76✔
317
    connect(m_addSpeedDialAction, SIGNAL(triggered(bool)), this, SLOT(slotAddSpeedDial()), Qt::QueuedConnection);
76✔
318

319
    m_addXYPadAction = new QAction(QIcon(":/xypad.png"), tr("New XY pad"), this);
76✔
320
    connect(m_addXYPadAction, SIGNAL(triggered(bool)), this, SLOT(slotAddXYPad()), Qt::QueuedConnection);
76✔
321

322
    m_addCueListAction = new QAction(QIcon(":/cuelist.png"), tr("New Cue list"), this);
76✔
323
    connect(m_addCueListAction, SIGNAL(triggered(bool)), this, SLOT(slotAddCueList()), Qt::QueuedConnection);
76✔
324

325
    m_addFrameAction = new QAction(QIcon(":/frame.png"), tr("New Frame"), this);
76✔
326
    connect(m_addFrameAction, SIGNAL(triggered(bool)), this, SLOT(slotAddFrame()), Qt::QueuedConnection);
76✔
327

328
    m_addSoloFrameAction = new QAction(QIcon(":/soloframe.png"), tr("New Solo frame"), this);
76✔
329
    connect(m_addSoloFrameAction, SIGNAL(triggered(bool)), this, SLOT(slotAddSoloFrame()), Qt::QueuedConnection);
76✔
330

331
    m_addLabelAction = new QAction(QIcon(":/label.png"), tr("New Label"), this);
76✔
332
    connect(m_addLabelAction, SIGNAL(triggered(bool)), this, SLOT(slotAddLabel()), Qt::QueuedConnection);
76✔
333

334
    m_addAudioTriggersAction = new QAction(QIcon(":/audioinput.png"), tr("New Audio Triggers"), this);
76✔
335
    connect(m_addAudioTriggersAction, SIGNAL(triggered(bool)), this, SLOT(slotAddAudioTriggers()), Qt::QueuedConnection);
76✔
336

337
    m_addClockAction = new QAction(QIcon(":/clock.png"), tr("New Clock"), this);
76✔
338
    connect(m_addClockAction, SIGNAL(triggered(bool)), this, SLOT(slotAddClock()), Qt::QueuedConnection);
76✔
339

340
    m_addAnimationAction = new QAction(QIcon(":/animation.png"), tr("New Animation"), this);
76✔
341
    connect(m_addAnimationAction, SIGNAL(triggered(bool)), this, SLOT(slotAddAnimation()), Qt::QueuedConnection);
76✔
342

343
    /* Put add actions under the same group */
344
    m_addActionGroup = new QActionGroup(this);
76✔
345
    m_addActionGroup->setExclusive(false);
76✔
346
    m_addActionGroup->addAction(m_addButtonAction);
76✔
347
    m_addActionGroup->addAction(m_addButtonMatrixAction);
76✔
348
    m_addActionGroup->addAction(m_addSliderAction);
76✔
349
    m_addActionGroup->addAction(m_addSliderMatrixAction);
76✔
350
    m_addActionGroup->addAction(m_addKnobAction);
76✔
351
    m_addActionGroup->addAction(m_addSpeedDialAction);
76✔
352
    m_addActionGroup->addAction(m_addXYPadAction);
76✔
353
    m_addActionGroup->addAction(m_addCueListAction);
76✔
354
    m_addActionGroup->addAction(m_addFrameAction);
76✔
355
    m_addActionGroup->addAction(m_addSoloFrameAction);
76✔
356
    m_addActionGroup->addAction(m_addLabelAction);
76✔
357
    m_addActionGroup->addAction(m_addAudioTriggersAction);
76✔
358
    m_addActionGroup->addAction(m_addClockAction);
76✔
359
    m_addActionGroup->addAction(m_addAnimationAction);
76✔
360

361
    /* Tools menu actions */
362
    m_toolsSettingsAction = new QAction(QIcon(":/configure.png"), tr("Virtual Console Settings"), this);
76✔
363
    connect(m_toolsSettingsAction, SIGNAL(triggered(bool)), this, SLOT(slotToolsSettings()));
76✔
364
    // Prevent this action from ending up to the application menu on OSX
365
    // and crashing the app after VC window is closed.
366
    m_toolsSettingsAction->setMenuRole(QAction::NoRole);
76✔
367

368
    /* Edit menu actions */
369
    m_editCutAction = new QAction(QIcon(":/editcut.png"), tr("Cut"), this);
76✔
370
    connect(m_editCutAction, SIGNAL(triggered(bool)), this, SLOT(slotEditCut()));
76✔
371

372
    m_editCopyAction = new QAction(QIcon(":/editcopy.png"), tr("Copy"), this);
76✔
373
    connect(m_editCopyAction, SIGNAL(triggered(bool)), this, SLOT(slotEditCopy()));
76✔
374

375
    m_editPasteAction = new QAction(QIcon(":/editpaste.png"), tr("Paste"), this);
76✔
376
    m_editPasteAction->setEnabled(false);
76✔
377
    connect(m_editPasteAction, SIGNAL(triggered(bool)), this, SLOT(slotEditPaste()));
76✔
378

379
    m_editDeleteAction = new QAction(QIcon(":/editdelete.png"), tr("Delete"), this);
76✔
380
    connect(m_editDeleteAction, SIGNAL(triggered(bool)), this, SLOT(slotEditDelete()));
76✔
381

382
    m_editPropertiesAction = new QAction(QIcon(":/edit.png"), tr("Widget Properties"), this);
76✔
383
    connect(m_editPropertiesAction, SIGNAL(triggered(bool)), this, SLOT(slotEditProperties()));
76✔
384

385
    m_editRenameAction = new QAction(QIcon(":/editclear.png"), tr("Rename Widget"), this);
76✔
386
    connect(m_editRenameAction, SIGNAL(triggered(bool)), this, SLOT(slotEditRename()));
76✔
387

388
    /* Put edit actions under the same group */
389
    m_editActionGroup = new QActionGroup(this);
76✔
390
    m_editActionGroup->setExclusive(false);
76✔
391
    m_editActionGroup->addAction(m_editCutAction);
76✔
392
    m_editActionGroup->addAction(m_editCopyAction);
76✔
393
    m_editActionGroup->addAction(m_editPasteAction);
76✔
394
    m_editActionGroup->addAction(m_editDeleteAction);
76✔
395
    m_editActionGroup->addAction(m_editPropertiesAction);
76✔
396
    m_editActionGroup->addAction(m_editRenameAction);
76✔
397

398
    /* Background menu actions */
399
    m_bgColorAction = new QAction(QIcon(":/color.png"), tr("Background Color"), this);
76✔
400
    connect(m_bgColorAction, SIGNAL(triggered(bool)), this, SLOT(slotBackgroundColor()));
76✔
401

402
    m_bgImageAction = new QAction(QIcon(":/image.png"), tr("Background Image"), this);
76✔
403
    connect(m_bgImageAction, SIGNAL(triggered(bool)), this, SLOT(slotBackgroundImage()));
76✔
404

405
    m_bgDefaultAction = new QAction(QIcon(":/undo.png"), tr("Default"), this);
76✔
406
    connect(m_bgDefaultAction, SIGNAL(triggered(bool)), this, SLOT(slotBackgroundNone()));
76✔
407

408
    /* Put BG actions under the same group */
409
    m_bgActionGroup = new QActionGroup(this);
76✔
410
    m_bgActionGroup->setExclusive(false);
76✔
411
    m_bgActionGroup->addAction(m_bgColorAction);
76✔
412
    m_bgActionGroup->addAction(m_bgImageAction);
76✔
413
    m_bgActionGroup->addAction(m_bgDefaultAction);
76✔
414

415
    /* Foreground menu actions */
416
    m_fgColorAction = new QAction(QIcon(":/fontcolor.png"), tr("Font Colour"), this);
76✔
417
    connect(m_fgColorAction, SIGNAL(triggered(bool)), this, SLOT(slotForegroundColor()));
76✔
418

419
    m_fgDefaultAction = new QAction(QIcon(":/undo.png"), tr("Default"), this);
76✔
420
    connect(m_fgDefaultAction, SIGNAL(triggered(bool)), this, SLOT(slotForegroundNone()));
76✔
421

422
    /* Put FG actions under the same group */
423
    m_fgActionGroup = new QActionGroup(this);
76✔
424
    m_fgActionGroup->setExclusive(false);
76✔
425
    m_fgActionGroup->addAction(m_fgColorAction);
76✔
426
    m_fgActionGroup->addAction(m_fgDefaultAction);
76✔
427

428
    /* Font menu actions */
429
    m_fontAction = new QAction(QIcon(":/fonts.png"), tr("Font"), this);
76✔
430
    connect(m_fontAction, SIGNAL(triggered(bool)), this, SLOT(slotFont()));
76✔
431

432
    m_resetFontAction = new QAction(QIcon(":/undo.png"), tr("Default"), this);
76✔
433
    connect(m_resetFontAction, SIGNAL(triggered(bool)), this, SLOT(slotResetFont()));
76✔
434

435
    /* Put font actions under the same group */
436
    m_fontActionGroup = new QActionGroup(this);
76✔
437
    m_fontActionGroup->setExclusive(false);
76✔
438
    m_fontActionGroup->addAction(m_fontAction);
76✔
439
    m_fontActionGroup->addAction(m_resetFontAction);
76✔
440

441
    /* Frame menu actions */
442
    m_frameSunkenAction = new QAction(QIcon(":/framesunken.png"), tr("Sunken"), this);
76✔
443
    connect(m_frameSunkenAction, SIGNAL(triggered(bool)), this, SLOT(slotFrameSunken()));
76✔
444

445
    m_frameRaisedAction = new QAction(QIcon(":/frameraised.png"), tr("Raised"), this);
76✔
446
    connect(m_frameRaisedAction, SIGNAL(triggered(bool)), this, SLOT(slotFrameRaised()));
76✔
447

448
    m_frameNoneAction = new QAction(QIcon(":/framenone.png"), tr("None"), this);
76✔
449
    connect(m_frameNoneAction, SIGNAL(triggered(bool)), this, SLOT(slotFrameNone()));
76✔
450

451
    /* Put frame actions under the same group */
452
    m_frameActionGroup = new QActionGroup(this);
76✔
453
    m_frameActionGroup->setExclusive(false);
76✔
454
    m_frameActionGroup->addAction(m_frameRaisedAction);
76✔
455
    m_frameActionGroup->addAction(m_frameSunkenAction);
76✔
456
    m_frameActionGroup->addAction(m_frameNoneAction);
76✔
457

458
    /* Stacking menu actions */
459
    m_stackingRaiseAction = new QAction(QIcon(":/up.png"), tr("Bring to front"), this);
76✔
460
    connect(m_stackingRaiseAction, SIGNAL(triggered(bool)), this, SLOT(slotStackingRaise()));
76✔
461

462
    m_stackingLowerAction = new QAction(QIcon(":/down.png"), tr("Send to back"), this);
76✔
463
    connect(m_stackingLowerAction, SIGNAL(triggered(bool)), this, SLOT(slotStackingLower()));
76✔
464

465
    /* Put stacking actions under the same group */
466
    m_stackingActionGroup = new QActionGroup(this);
76✔
467
    m_stackingActionGroup->setExclusive(false);
76✔
468
    m_stackingActionGroup->addAction(m_stackingRaiseAction);
76✔
469
    m_stackingActionGroup->addAction(m_stackingLowerAction);
76✔
470
}
76✔
471

472
void VirtualConsole::initMenuBar()
76✔
473
{
474
    /* Add menu */
475
    m_addMenu = new QMenu(this);
76✔
476
    m_addMenu->setTitle(tr("&Add"));
76✔
477
    m_addMenu->addAction(m_addButtonAction);
76✔
478
    m_addMenu->addAction(m_addButtonMatrixAction);
76✔
479
    m_addMenu->addSeparator();
76✔
480
    m_addMenu->addAction(m_addSliderAction);
76✔
481
    m_addMenu->addAction(m_addSliderMatrixAction);
76✔
482
    m_addMenu->addAction(m_addKnobAction);
76✔
483
    m_addMenu->addAction(m_addSpeedDialAction);
76✔
484
    m_addMenu->addSeparator();
76✔
485
    m_addMenu->addAction(m_addXYPadAction);
76✔
486
    m_addMenu->addAction(m_addCueListAction);
76✔
487
    m_addMenu->addAction(m_addAnimationAction);
76✔
488
    m_addMenu->addAction(m_addAudioTriggersAction);
76✔
489
    m_addMenu->addSeparator();
76✔
490
    m_addMenu->addAction(m_addFrameAction);
76✔
491
    m_addMenu->addAction(m_addSoloFrameAction);
76✔
492
    m_addMenu->addAction(m_addLabelAction);
76✔
493
    m_addMenu->addAction(m_addClockAction);
76✔
494

495
    /* Edit menu */
496
    m_editMenu = new QMenu(this);
76✔
497
    m_editMenu->setTitle(tr("&Edit"));
76✔
498
    m_editMenu->addAction(m_editCutAction);
76✔
499
    m_editMenu->addAction(m_editCopyAction);
76✔
500
    m_editMenu->addAction(m_editPasteAction);
76✔
501
    m_editMenu->addAction(m_editDeleteAction);
76✔
502
    m_editMenu->addSeparator();
76✔
503
    m_editMenu->addAction(m_editPropertiesAction);
76✔
504
    m_editMenu->addAction(m_editRenameAction);
76✔
505
    m_editMenu->addSeparator();
76✔
506

507
    /* Background Menu */
508
    QMenu* bgMenu = new QMenu(m_editMenu);
76✔
509
    bgMenu->setTitle(tr("&Background"));
76✔
510
    m_editMenu->addMenu(bgMenu);
76✔
511
    bgMenu->addAction(m_bgColorAction);
76✔
512
    bgMenu->addAction(m_bgImageAction);
76✔
513
    bgMenu->addAction(m_bgDefaultAction);
76✔
514

515
    /* Foreground menu */
516
    QMenu* fgMenu = new QMenu(m_editMenu);
76✔
517
    fgMenu->setTitle(tr("&Foreground"));
76✔
518
    m_editMenu->addMenu(fgMenu);
76✔
519
    fgMenu->addAction(m_fgColorAction);
76✔
520
    fgMenu->addAction(m_fgDefaultAction);
76✔
521

522
    /* Font menu */
523
    QMenu* fontMenu = new QMenu(m_editMenu);
76✔
524
    fontMenu->setTitle(tr("F&ont"));
76✔
525
    m_editMenu->addMenu(fontMenu);
76✔
526
    fontMenu->addAction(m_fontAction);
76✔
527
    fontMenu->addAction(m_resetFontAction);
76✔
528

529
    /* Frame menu */
530
    QMenu* frameMenu = new QMenu(m_editMenu);
76✔
531
    frameMenu->setTitle(tr("F&rame"));
76✔
532
    m_editMenu->addMenu(frameMenu);
76✔
533
    frameMenu->addAction(m_frameSunkenAction);
76✔
534
    frameMenu->addAction(m_frameRaisedAction);
76✔
535
    frameMenu->addAction(m_frameNoneAction);
76✔
536

537
    /* Stacking order menu */
538
    QMenu* stackMenu = new QMenu(m_editMenu);
76✔
539
    stackMenu->setTitle(tr("Stacking &order"));
76✔
540
    m_editMenu->addMenu(stackMenu);
76✔
541
    stackMenu->addAction(m_stackingRaiseAction);
76✔
542
    stackMenu->addAction(m_stackingLowerAction);
76✔
543

544
    /* Add a separator that separates the common edit items from a custom
545
       widget menu that gets appended to the edit menu when a selected
546
       widget provides one. */
547
    m_editMenu->addSeparator();
76✔
548

549
    /* Toolbar */
550
    m_toolbar = new QToolBar(this);
76✔
551
    m_toolbar->setIconSize(QSize(26,26));
76✔
552
    m_contentsLayout->addWidget(m_toolbar);
76✔
553

554
    m_toolbar->addAction(m_addButtonAction);
76✔
555
    m_toolbar->addAction(m_addButtonMatrixAction);
76✔
556
    m_toolbar->addAction(m_addSliderAction);
76✔
557
    m_toolbar->addAction(m_addSliderMatrixAction);
76✔
558
    m_toolbar->addAction(m_addKnobAction);
76✔
559
    m_toolbar->addAction(m_addSpeedDialAction);
76✔
560
    m_toolbar->addAction(m_addXYPadAction);
76✔
561
    m_toolbar->addAction(m_addCueListAction);
76✔
562
    m_toolbar->addAction(m_addAnimationAction);
76✔
563
    m_toolbar->addAction(m_addFrameAction);
76✔
564
    m_toolbar->addAction(m_addSoloFrameAction);
76✔
565
    m_toolbar->addAction(m_addLabelAction);
76✔
566
    m_toolbar->addAction(m_addAudioTriggersAction);
76✔
567
    m_toolbar->addAction(m_addClockAction);
76✔
568
    m_toolbar->addSeparator();
76✔
569
    m_toolbar->addAction(m_editCutAction);
76✔
570
    m_toolbar->addAction(m_editCopyAction);
76✔
571
    m_toolbar->addAction(m_editPasteAction);
76✔
572
    m_toolbar->addSeparator();
76✔
573
    m_toolbar->addAction(m_editDeleteAction);
76✔
574
    m_toolbar->addSeparator();
76✔
575
    m_toolbar->addAction(m_editPropertiesAction);
76✔
576
    m_toolbar->addAction(m_editRenameAction);
76✔
577
    m_toolbar->addSeparator();
76✔
578
    m_toolbar->addAction(m_stackingRaiseAction);
76✔
579
    m_toolbar->addAction(m_stackingLowerAction);
76✔
580
    m_toolbar->addSeparator();
76✔
581
    m_toolbar->addAction(m_bgColorAction);
76✔
582
    m_toolbar->addAction(m_bgImageAction);
76✔
583
    m_toolbar->addAction(m_fgColorAction);
76✔
584
    m_toolbar->addAction(m_fontAction);
76✔
585
    m_toolbar->addSeparator();
76✔
586
    m_toolbar->addAction(m_toolsSettingsAction);
76✔
587
}
76✔
588

589
void VirtualConsole::updateCustomMenu()
10✔
590
{
591
    /* Get rid of the custom menu, but delete it later because this might
592
       be called from the very menu that is being deleted. */
593
    if (m_customMenu != NULL)
10✔
594
    {
595
        delete m_customMenu;
6✔
596
        m_customMenu = NULL;
6✔
597
    }
598

599
    if (m_selectedWidgets.size() > 0)
10✔
600
    {
601
        /* Change the custom menu to the last selected widget's menu */
602
        VCWidget* latestWidget = m_selectedWidgets.last();
4✔
603
        m_customMenu = latestWidget->customMenu(m_editMenu);
4✔
604
        if (m_customMenu != NULL)
4✔
605
            m_editMenu->addMenu(m_customMenu);
2✔
606
    }
607
    else
608
    {
609
        /* Change the custom menu to the bottom frame's menu */
610
        Q_ASSERT(contents() != NULL);
6✔
611
        m_customMenu = contents()->customMenu(m_editMenu);
6✔
612
        if (m_customMenu != NULL)
6✔
613
            m_editMenu->addMenu(m_customMenu);
6✔
614
    }
615
}
10✔
616

617
void VirtualConsole::updateActions()
162✔
618
{
619
    /* When selected widgets is empty, all actions go to main draw area. */
620
    if (m_selectedWidgets.isEmpty() == true)
162✔
621
    {
622
        /* Enable widget additions to draw area */
623
        m_addActionGroup->setEnabled(true);
158✔
624

625
        /* Disable edit actions that can't be allowed for draw area */
626
        m_editCutAction->setEnabled(false);
158✔
627
        m_editCopyAction->setEnabled(false);
158✔
628
        m_editDeleteAction->setEnabled(false);
158✔
629
        m_editRenameAction->setEnabled(false);
158✔
630
        m_editPropertiesAction->setEnabled(false);
158✔
631

632
        /* All the rest are disabled for draw area, except BG & font */
633
        m_frameActionGroup->setEnabled(false);
158✔
634
        m_stackingActionGroup->setEnabled(false);
158✔
635

636
        /* Enable paste to draw area if there's something to paste */
637
        if (m_clipboard.isEmpty() == true)
158✔
638
            m_editPasteAction->setEnabled(false);
158✔
639
        else
640
            m_editPasteAction->setEnabled(true);
×
641
    }
642
    else
643
    {
644
        /* Enable edit actions for other widgets */
645
        m_editCutAction->setEnabled(true);
4✔
646
        m_editCopyAction->setEnabled(true);
4✔
647
        m_editDeleteAction->setEnabled(true);
4✔
648
        m_editRenameAction->setEnabled(true);
4✔
649
        m_editPropertiesAction->setEnabled(true);
4✔
650

651
        /* Enable all common properties */
652
        m_bgActionGroup->setEnabled(true);
4✔
653
        m_fgActionGroup->setEnabled(true);
4✔
654
        m_fontActionGroup->setEnabled(true);
4✔
655
        m_frameActionGroup->setEnabled(true);
4✔
656
        m_stackingActionGroup->setEnabled(true);
4✔
657

658
        /* Check, whether the last selected widget can hold children */
659
        if (m_selectedWidgets.last()->allowChildren() == true)
4✔
660
        {
661
            /* Enable paste for widgets that can hold children */
662
            if (m_clipboard.isEmpty() == true)
1✔
663
                m_editPasteAction->setEnabled(false);
1✔
664
            else
665
                m_editPasteAction->setEnabled(true);
×
666

667
            /* Enable also new additions */
668
            m_addActionGroup->setEnabled(true);
1✔
669
        }
670
        else
671
        {
672
            /* No pasted children possible */
673
            m_editPasteAction->setEnabled(false);
3✔
674
        }
675
    }
676

677
    if (contents()->children().count() == 0)
162✔
678
        m_latestWidgetId = 0;
156✔
679
}
162✔
680

681
/*****************************************************************************
682
 * Add menu callbacks
683
 *****************************************************************************/
684

685
VCWidget* VirtualConsole::closestParent() const
×
686
{
687
    /* If nothing is selected, return the bottom-most contents frame */
688
    if (m_selectedWidgets.isEmpty() == true)
×
689
        return contents();
×
690

691
    /* Find the next VCWidget in the hierarchy that accepts children */
692
    VCWidget* widget = m_selectedWidgets.last();
×
693
    while (widget != NULL)
×
694
    {
695
        if (widget->allowChildren() == true)
×
696
            return widget;
×
697
        else
698
            widget = qobject_cast<VCWidget*> (widget->parentWidget());
×
699
    }
700

701
    return NULL;
×
702
}
703

704
void VirtualConsole::connectWidgetToParent(VCWidget *widget, VCWidget *parent)
×
705
{
706
    if (parent->type() == VCWidget::FrameWidget
×
707
            || parent->type() == VCWidget::SoloFrameWidget)
×
708
    {
709
        VCFrame *frame = qobject_cast<VCFrame *>(parent);
×
710
        if (frame != NULL)
×
711
        {
712
            widget->setPage(frame->currentPage());
×
713
            frame->addWidgetToPageMap(widget);
×
714
        }
715
    }
716
    else
717
        widget->setPage(0);
×
718

719
    if (widget->type() == VCWidget::SliderWidget)
×
720
    {
721
        VCSlider *slider = qobject_cast<VCSlider *>(widget);
×
722
        if (slider != NULL)
×
723
        {
724
            connect(slider, SIGNAL(submasterValueChanged(qreal)),
×
725
                    parent, SLOT(slotSubmasterValueChanged(qreal)));
726
        }
727
    }
728
}
×
729

730
void VirtualConsole::disconnectWidgetFromParent(VCWidget *widget, VCWidget *parent)
×
731
{
732
    if (parent->type() == VCWidget::FrameWidget
×
733
            || parent->type() == VCWidget::SoloFrameWidget)
×
734
    {
735
        VCFrame *frame = qobject_cast<VCFrame *>(parent);
×
736
        if (frame != NULL)
×
737
            frame->removeWidgetFromPageMap(widget);
×
738
    }
739

740
    if (widget->type() == VCWidget::SliderWidget)
×
741
    {
742
        VCSlider *slider = qobject_cast<VCSlider *>(widget);
×
743
        if (slider != NULL)
×
744
        {
745
            disconnect(slider, SIGNAL(submasterValueChanged(qreal)),
×
746
                       parent, SLOT(slotSubmasterValueChanged(qreal)));
747
        }
748
    }
749
}
×
750

751
void VirtualConsole::slotAddButton()
×
752
{
753
    VCWidget* parent(closestParent());
×
754
    if (parent == NULL)
×
755
        return;
×
756

757
    VCButton* button = new VCButton(parent, m_doc);
×
758
    setupWidget(button, parent);
×
759
    m_doc->setModified();
×
760
}
761

762
void VirtualConsole::slotAddButtonMatrix()
×
763
{
764
    VCWidget* parent(closestParent());
×
765
    if (parent == NULL)
×
766
        return;
×
767

768
    AddVCButtonMatrix abm(this, m_doc);
×
769
    if (abm.exec() == QDialog::Rejected)
×
770
        return;
×
771

772
    int h = abm.horizontalCount();
×
773
    int v = abm.verticalCount();
×
774
    int sz = abm.buttonSize();
×
775

776
    VCFrame* frame = NULL;
×
777
    if (abm.frameStyle() == AddVCButtonMatrix::NormalFrame)
×
778
        frame = new VCFrame(parent, m_doc);
×
779
    else
780
        frame = new VCSoloFrame(parent, m_doc);
×
781
    Q_ASSERT(frame != NULL);
×
782
    addWidgetInMap(frame);
×
783
    frame->setHeaderVisible(false);
×
784
    connectWidgetToParent(frame, parent);
×
785

786
    // Resize the parent frame to fit the buttons nicely and toggle resizing off
787
    frame->resize(QSize((h * sz) + 20, (v * sz) + 20));
×
788
    frame->setAllowResize(false);
×
789

790
    for (int y = 0; y < v; y++)
×
791
    {
792
        for (int x = 0; x < h; x++)
×
793
        {
794
            VCButton* button = new VCButton(frame, m_doc);
×
795
            Q_ASSERT(button != NULL);
×
796
            addWidgetInMap(button);
×
797
            connectWidgetToParent(button, frame);
×
798
            button->move(QPoint(10 + (x * sz), 10 + (y * sz)));
×
799
            button->resize(QSize(sz, sz));
×
800
            button->show();
×
801

802
            int index = (y * h) + x;
×
803
            if (index < abm.functions().size())
×
804
            {
805
                quint32 fid = abm.functions().at(index);
×
806
                Function* function = m_doc->function(fid);
×
807
                if (function != NULL)
×
808
                {
809
                    button->setFunction(fid);
×
810
                    button->setCaption(function->name());
×
811
                }
812
            }
813
        }
814
    }
815

816
    // Show the frame after adding buttons to prevent flickering
817
    frame->show();
×
818
    frame->move(parent->lastClickPoint());
×
819
    frame->setAllowChildren(false); // Don't allow more children
×
820
    clearWidgetSelection();
×
821
    setWidgetSelected(frame, true);
×
822
    m_doc->setModified();
×
823
}
824

825
void VirtualConsole::slotAddSlider()
×
826
{
827
    VCWidget* parent(closestParent());
×
828
    if (parent == NULL)
×
829
        return;
×
830

831
    VCSlider* slider = new VCSlider(parent, m_doc);
×
832
    setupWidget(slider, parent);
×
833
    m_doc->setModified();
×
834
}
835

836
void VirtualConsole::slotAddSliderMatrix()
×
837
{
838
    VCWidget* parent(closestParent());
×
839
    if (parent == NULL)
×
840
        return;
×
841

842
    AddVCSliderMatrix avsm(this);
×
843
    if (avsm.exec() == QDialog::Rejected)
×
844
        return;
×
845

846
    int width = avsm.width();
×
847
    int height = avsm.height();
×
848
    int count = avsm.amount();
×
849

850
    VCFrame* frame = new VCFrame(parent, m_doc);
×
851
    Q_ASSERT(frame != NULL);
×
852
    addWidgetInMap(frame);
×
853
    frame->setHeaderVisible(false);
×
854
    connectWidgetToParent(frame, parent);
×
855

856
    // Resize the parent frame to fit the sliders nicely
857
    frame->resize(QSize((count * width) + 20, height + 20));
×
858
    frame->setAllowResize(false);
×
859

860
    for (int i = 0; i < count; i++)
×
861
    {
862
        VCSlider* slider = new VCSlider(frame, m_doc);
×
863
        Q_ASSERT(slider != NULL);
×
864
        addWidgetInMap(slider);
×
865
        connectWidgetToParent(slider, frame);
×
866
        slider->move(QPoint(10 + (width * i), 10));
×
867
        slider->resize(QSize(width, height));
×
868
        slider->show();
×
869
    }
870

871
    // Show the frame after adding buttons to prevent flickering
872
    frame->show();
×
873
    frame->move(parent->lastClickPoint());
×
874
    frame->setAllowChildren(false); // Don't allow more children
×
875
    clearWidgetSelection();
×
876
    setWidgetSelected(frame, true);
×
877
    m_doc->setModified();
×
878
}
879

880
void VirtualConsole::slotAddKnob()
×
881
{
882
    VCWidget* parent(closestParent());
×
883
    if (parent == NULL)
×
884
        return;
×
885

886
    VCSlider* knob = new VCSlider(parent, m_doc);
×
887
    setupWidget(knob, parent);
×
888
    knob->resize(QSize(60, 90));
×
889
    knob->setWidgetStyle(VCSlider::WKnob);
×
890
    knob->setCaption(tr("Knob %1").arg(knob->id()));
×
891
    m_doc->setModified();
×
892
}
893

894
void VirtualConsole::slotAddSpeedDial()
×
895
{
896
    VCWidget* parent(closestParent());
×
897
    if (parent == NULL)
×
898
        return;
×
899

900
    VCSpeedDial* dial = new VCSpeedDial(parent, m_doc);
×
901
    setupWidget(dial, parent);
×
902
    m_doc->setModified();
×
903
}
904

905
void VirtualConsole::slotAddXYPad()
×
906
{
907
    VCWidget* parent(closestParent());
×
908
    if (parent == NULL)
×
909
        return;
×
910

911
    VCXYPad* xypad = new VCXYPad(parent, m_doc);
×
912
    setupWidget(xypad, parent);
×
913
    m_doc->setModified();
×
914
}
915

916
void VirtualConsole::slotAddCueList()
×
917
{
918
    VCWidget* parent(closestParent());
×
919
    if (parent == NULL)
×
920
        return;
×
921

922
    VCCueList* cuelist = new VCCueList(parent, m_doc);
×
923
    setupWidget(cuelist, parent);
×
924
    m_doc->setModified();
×
925
}
926

927
void VirtualConsole::slotAddFrame()
×
928
{
929
    VCWidget* parent(closestParent());
×
930
    if (parent == NULL)
×
931
        return;
×
932

933
    VCFrame* frame = new VCFrame(parent, m_doc, true);
×
934
    setupWidget(frame, parent);
×
935
    m_doc->setModified();
×
936
}
937

938
void VirtualConsole::slotAddSoloFrame()
×
939
{
940
    VCWidget* parent(closestParent());
×
941
    if (parent == NULL)
×
942
        return;
×
943

944
    VCSoloFrame* soloframe = new VCSoloFrame(parent, m_doc, true);
×
945
    setupWidget(soloframe, parent);
×
946
    m_doc->setModified();
×
947
}
948

949
void VirtualConsole::slotAddLabel()
×
950
{
951
    VCWidget* parent(closestParent());
×
952
    if (parent == NULL)
×
953
        return;
×
954

955
    VCLabel* label = new VCLabel(parent, m_doc);
×
956
    setupWidget(label, parent);
×
957
    m_doc->setModified();
×
958
}
959

960
void VirtualConsole::slotAddAudioTriggers()
×
961
{
962
    VCWidget* parent(closestParent());
×
963
    if (parent == NULL)
×
964
        return;
×
965

966
    VCAudioTriggers* triggers = new VCAudioTriggers(parent, m_doc);
×
967
    setupWidget(triggers, parent);
×
968
    m_doc->setModified();
×
969
}
970

971
void VirtualConsole::slotAddClock()
×
972
{
973
    VCWidget* parent(closestParent());
×
974
    if (parent == NULL)
×
975
        return;
×
976

977
    VCClock* clock = new VCClock(parent, m_doc);
×
978
    setupWidget(clock, parent);
×
979
    m_doc->setModified();
×
980
}
981

982
void VirtualConsole::slotAddAnimation()
×
983
{
984
    VCWidget* parent(closestParent());
×
985
    if (parent == NULL)
×
986
        return;
×
987

988
    VCMatrix* matrix = new VCMatrix(parent, m_doc);
×
989
    setupWidget(matrix, parent);
×
990
    m_doc->setModified();
×
991
}
992

993
/*****************************************************************************
994
 * Tools menu callbacks
995
 *****************************************************************************/
996

997
void VirtualConsole::slotToolsSettings()
×
998
{
999
    VCPropertiesEditor vcpe(this, m_properties, m_doc->inputOutputMap());
×
1000
    if (vcpe.exec() == QDialog::Accepted)
×
1001
    {
1002
        m_properties = vcpe.properties();
×
1003
        contents()->resize(m_properties.size());
×
1004
        m_doc->inputOutputMap()->setGrandMasterChannelMode(m_properties.grandMasterChannelMode());
×
1005
        m_doc->inputOutputMap()->setGrandMasterValueMode(m_properties.grandMasterValueMode());
×
1006
        if (m_dockArea != NULL)
×
1007
            m_dockArea->setGrandMasterInvertedAppearance(m_properties.grandMasterSlideMode());
×
1008

1009
        m_doc->setFlashOverrides(m_properties.flashOverrides());
×
1010
        m_doc->setFlashForceLTP(m_properties.flashForceLTP());
×
1011

1012
        QSettings settings;
×
1013
        settings.setValue(SETTINGS_BUTTON_SIZE, vcpe.buttonSize());
×
1014
        settings.setValue(SETTINGS_BUTTON_STATUSLED, vcpe.buttonStatusLED());
×
1015
        settings.setValue(SETTINGS_SLIDER_SIZE, vcpe.sliderSize());
×
1016
        settings.setValue(SETTINGS_SPEEDDIAL_SIZE, vcpe.speedDialSize());
×
1017
        settings.setValue(SETTINGS_SPEEDDIAL_VALUE, vcpe.speedDialValue());
×
1018
        settings.setValue(SETTINGS_XYPAD_SIZE, vcpe.xypadSize());
×
1019
        settings.setValue(SETTINGS_CUELIST_SIZE, vcpe.cuelistSize());
×
1020
        settings.setValue(SETTINGS_FRAME_SIZE, vcpe.frameSize());
×
1021
        settings.setValue(SETTINGS_SOLOFRAME_SIZE, vcpe.soloFrameSize());
×
1022
        settings.setValue(SETTINGS_AUDIOTRIGGERS_SIZE, vcpe.audioTriggersSize());
×
1023
        settings.setValue(SETTINGS_RGBMATRIX_SIZE, vcpe.rgbMatrixSize());
×
1024

1025
        m_doc->setModified();
×
1026
    }
1027
}
×
1028

1029
/*****************************************************************************
1030
 * Edit menu callbacks
1031
 *****************************************************************************/
1032

1033
void VirtualConsole::slotEditCut()
×
1034
{
1035
    /* No need to delete widgets in clipboard because they are actually just
1036
       MOVED to another parent during Paste when m_editAction == EditCut.
1037
       Cutting the widgets does nothing to them unless Paste is invoked. */
1038

1039
    /* Make the edit action valid only if there's something to cut */
1040
    if (m_selectedWidgets.size() == 0)
×
1041
    {
1042
        m_editAction = EditNone;
×
1043
        m_clipboard.clear();
×
1044
        m_editPasteAction->setEnabled(false);
×
1045
    }
1046
    else
1047
    {
1048
        m_editAction = EditCut;
×
1049
        m_clipboard = m_selectedWidgets;
×
1050
        m_editPasteAction->setEnabled(true);
×
1051
    }
1052

1053
    updateActions();
×
1054
}
×
1055

1056
void VirtualConsole::slotEditCopy()
×
1057
{
1058
    /* Make the edit action valid only if there's something to copy */
1059
    if (m_selectedWidgets.size() == 0)
×
1060
    {
1061
        m_editAction = EditNone;
×
1062
        m_clipboard.clear();
×
1063
        m_editPasteAction->setEnabled(false);
×
1064
    }
1065
    else
1066
    {
1067
        m_editAction = EditCopy;
×
1068
        m_clipboard = m_selectedWidgets;
×
1069
        m_editPasteAction->setEnabled(true);
×
1070
    }
1071
}
×
1072

1073
void VirtualConsole::slotEditPaste()
×
1074
{
1075
    if (m_clipboard.size() == 0)
×
1076
    {
1077
        /* Invalidate the edit action if there's nothing to paste */
1078
        m_editAction = EditNone;
×
1079
        m_editPasteAction->setEnabled(false);
×
1080
        return;
×
1081
    }
1082

1083
    VCWidget* parent;
1084
    VCWidget* widget;
1085
    QRect bounds;
×
1086

1087
    Q_ASSERT(contents() != NULL);
×
1088

1089
    /* Select the parent that gets the cut clipboard contents */
1090
    parent = closestParent();
×
1091

1092
    /* Get the bounding rect for all selected widgets */
1093
    QListIterator <VCWidget*> it(m_clipboard);
×
1094
    while (it.hasNext() == true)
×
1095
    {
1096
        widget = it.next();
×
1097
        Q_ASSERT(widget != NULL);
×
1098
        bounds = bounds.united(widget->geometry());
×
1099
    }
1100

1101
    /* Get the upcoming parent's last mouse click point */
1102
    QPoint cp(parent->lastClickPoint());
×
1103

1104
    if (m_editAction == EditCut)
×
1105
    {
1106
        it.toFront();
×
1107
        while (it.hasNext() == true)
×
1108
        {
1109
            widget = it.next();
×
1110
            Q_ASSERT(widget != NULL);
×
1111
            if (widget == parent)
×
1112
                continue;
×
1113

1114
            VCWidget* prevParent = qobject_cast<VCWidget*> (widget->parentWidget());
×
1115
            if (prevParent != NULL)
×
1116
                disconnectWidgetFromParent(widget, prevParent);
×
1117

1118
            /* Get widget's relative pos to the bounding rect */
1119
            QPoint p(widget->x() - bounds.x() + cp.x(),
×
1120
                     widget->y() - bounds.y() + cp.y());
×
1121

1122
            /* Reparent and move to the correct place */
1123
            widget->setParent(parent);
×
1124
            connectWidgetToParent(widget, parent);
×
1125
            widget->move(p);
×
1126
            widget->show();
×
1127
        }
1128

1129
        /* Clear clipboard after pasting stuff that was CUT */
1130
        m_clipboard.clear();
×
1131
        m_editPasteAction->setEnabled(false);
×
1132
    }
1133
    else if (m_editAction == EditCopy)
×
1134
    {
1135
        it.toFront();
×
1136
        while (it.hasNext() == true)
×
1137
        {
1138
            widget = it.next();
×
1139
            Q_ASSERT(widget != NULL);
×
1140
            if (widget == parent)
×
1141
                continue;
×
1142

1143
            /* Get widget's relative pos to the bounding rect */
1144
            QPoint p(widget->x() - bounds.x() + cp.x(),
×
1145
                     widget->y() - bounds.y() + cp.y());
×
1146

1147
            /* Create a copy and move to correct place */
1148
            VCWidget* copy = widget->createCopy(parent);
×
1149
            Q_ASSERT(copy != NULL);
×
1150
            addWidgetInMap(copy);
×
1151
            connectWidgetToParent(copy, parent);
×
1152
            copy->move(p);
×
1153
            copy->show();
×
1154
        }
1155
    }
1156

1157
    updateActions();
×
1158
}
1159

1160
void VirtualConsole::slotEditDelete()
×
1161
{
1162
    QString msg(tr("Do you wish to delete the selected widgets?"));
×
1163
    QString title(tr("Delete widgets"));
×
1164
    int result = QMessageBox::question(this, title, msg,
×
1165
                                       QMessageBox::Yes,
1166
                                       QMessageBox::No);
1167
    if (result == QMessageBox::Yes)
×
1168
    {
1169
        while (m_selectedWidgets.isEmpty() == false)
×
1170
        {
1171
            /* Consume the selected list until it is empty and
1172
               delete each widget. */
1173
            VCWidget* widget = m_selectedWidgets.takeFirst();
×
1174
            m_widgetsMap.remove(widget->id());
×
1175
            foreach (VCWidget* child, getChildren(widget))
×
1176
                m_widgetsMap.remove(child->id());
×
1177
            VCWidget* parent = qobject_cast<VCWidget*> (widget->parentWidget());
×
1178
            widget->deleteLater();
×
1179

1180
            if (parent != NULL)
×
1181
                disconnectWidgetFromParent(widget, parent);
×
1182

1183
            /* Remove the widget from clipboard as well so that
1184
               deleted widgets won't be pasted anymore anywhere */
1185
            m_clipboard.removeAll(widget);
×
1186
            m_editPasteAction->setEnabled(false);
×
1187
        }
1188

1189
        updateActions();
×
1190
    }
1191
    m_doc->setModified();
×
1192
}
×
1193

1194
void VirtualConsole::slotEditProperties()
×
1195
{
1196
    VCWidget* widget;
1197

1198
    Q_ASSERT(contents() != NULL);
×
1199

1200
    if (m_selectedWidgets.isEmpty() == true)
×
1201
        widget = contents();
×
1202
    else
1203
        widget = m_selectedWidgets.last();
×
1204

1205
    if (widget != NULL)
×
1206
        widget->editProperties();
×
1207
}
×
1208

1209
void VirtualConsole::slotEditRename()
×
1210
{
1211
    if (m_selectedWidgets.isEmpty() == true)
×
1212
        return;
×
1213

1214
    bool ok = false;
×
1215
    QString text(m_selectedWidgets.last()->caption());
×
1216
    text = QInputDialog::getText(this, tr("Rename widgets"), tr("Caption:"),
×
1217
                                 QLineEdit::Normal, text, &ok);
×
1218
    if (ok == true)
×
1219
    {
1220
        VCWidget* widget;
1221
        foreach(widget, m_selectedWidgets)
×
1222
            widget->setCaption(text);
×
1223
    }
1224
}
1225

1226
/*****************************************************************************
1227
 * Background menu callbacks
1228
 *****************************************************************************/
1229

1230
void VirtualConsole::slotBackgroundColor()
×
1231
{
1232
    QColor color;
×
1233

1234
    Q_ASSERT(contents() != NULL);
×
1235

1236
    if (m_selectedWidgets.isEmpty() == true)
×
1237
        color = contents()->backgroundColor();
×
1238
    else
1239
        color = m_selectedWidgets.last()->backgroundColor();
×
1240

1241
    color = QColorDialog::getColor(color);
×
1242
    if (color.isValid() == true)
×
1243
    {
1244
        if (m_selectedWidgets.isEmpty() == true)
×
1245
        {
1246
            contents()->setBackgroundColor(color);
×
1247
        }
1248
        else
1249
        {
1250
            VCWidget* widget;
1251
            foreach(widget, m_selectedWidgets)
×
1252
                widget->setBackgroundColor(color);
×
1253
        }
1254
    }
1255
}
×
1256

1257
void VirtualConsole::slotBackgroundImage()
×
1258
{
1259
    QString path;
×
1260

1261
    Q_ASSERT(contents() != NULL);
×
1262

1263
    if (m_selectedWidgets.isEmpty() == true)
×
1264
        path = contents()->backgroundImage();
×
1265
    else
1266
        path = m_selectedWidgets.last()->backgroundImage();
×
1267

1268
    path = QFileDialog::getOpenFileName(this,
×
1269
                                        tr("Select background image"),
×
1270
                                        path,
1271
                                        QString("%1 (*.png *.bmp *.jpg *.jpeg *.gif)").arg(tr("Images")));
×
1272
    if (path.isEmpty() == false)
×
1273
    {
1274
        if (m_selectedWidgets.isEmpty() == true)
×
1275
        {
1276
            contents()->setBackgroundImage(path);
×
1277
        }
1278
        else
1279
        {
1280
            VCWidget* widget;
1281
            foreach(widget, m_selectedWidgets)
×
1282
                widget->setBackgroundImage(path);
×
1283
        }
1284
    }
1285
}
×
1286

1287
void VirtualConsole::slotBackgroundNone()
×
1288
{
1289
    Q_ASSERT(contents() != NULL);
×
1290

1291
    if (m_selectedWidgets.isEmpty() == true)
×
1292
    {
1293
        contents()->resetBackgroundColor();
×
1294
    }
1295
    else
1296
    {
1297
        VCWidget* widget;
1298
        foreach(widget, m_selectedWidgets)
×
1299
            widget->resetBackgroundColor();
×
1300
    }
1301
}
×
1302

1303
/*****************************************************************************
1304
 * Foreground menu callbacks
1305
 *****************************************************************************/
1306

1307
void VirtualConsole::slotForegroundColor()
×
1308
{
1309
    Q_ASSERT(contents() != NULL);
×
1310

1311
    if (m_selectedWidgets.isEmpty() == true)
×
1312
        return;
×
1313

1314
    QColor color(m_selectedWidgets.last()->foregroundColor());
×
1315
    color = QColorDialog::getColor(color);
×
1316
    if (color.isValid() == true)
×
1317
    {
1318
        VCWidget* widget;
1319
        foreach(widget, m_selectedWidgets)
×
1320
            widget->setForegroundColor(color);
×
1321
    }
1322
}
1323

1324
void VirtualConsole::slotForegroundNone()
×
1325
{
1326
    Q_ASSERT(contents() != NULL);
×
1327

1328
    if (m_selectedWidgets.isEmpty() == true)
×
1329
        return;
×
1330

1331
    VCWidget* widget;
1332
    foreach(widget, m_selectedWidgets)
×
1333
        widget->resetForegroundColor();
×
1334
}
1335

1336
/*****************************************************************************
1337
 * Font menu callbacks
1338
 *****************************************************************************/
1339

1340
void VirtualConsole::slotFont()
×
1341
{
1342
    bool ok = false;
×
1343
    QFont font;
×
1344

1345
    Q_ASSERT(contents() != NULL);
×
1346

1347
    if (m_selectedWidgets.isEmpty() == true)
×
1348
        font = contents()->font();
×
1349
    else
1350
        font = m_selectedWidgets.last()->font();
×
1351

1352
    /* This crashes with Qt 4.6.x on OSX. Upgrade to 4.7.x. */
1353
    font = QFontDialog::getFont(&ok, font);
×
1354
    if (ok == true)
×
1355
    {
1356
        if (m_selectedWidgets.isEmpty() == true)
×
1357
        {
1358
            contents()->setFont(font);
×
1359
        }
1360
        else
1361
        {
1362
            VCWidget* widget;
1363
            foreach(widget, m_selectedWidgets)
×
1364
                widget->setFont(font);
×
1365
        }
1366
    }
1367
}
×
1368

1369
void VirtualConsole::slotResetFont()
×
1370
{
1371
    Q_ASSERT(contents() != NULL);
×
1372

1373
    if (m_selectedWidgets.isEmpty() == true)
×
1374
    {
1375
        contents()->resetFont();
×
1376
    }
1377
    else
1378
    {
1379
        VCWidget* widget;
1380
        foreach(widget, m_selectedWidgets)
×
1381
            widget->resetFont();
×
1382
    }
1383
}
×
1384

1385
/*****************************************************************************
1386
 * Stacking menu callbacks
1387
 *****************************************************************************/
1388

1389
void VirtualConsole::slotStackingRaise()
×
1390
{
1391
    Q_ASSERT(contents() != NULL);
×
1392

1393
    if (m_selectedWidgets.isEmpty() == true)
×
1394
        return;
×
1395

1396
    VCWidget* widget;
1397
    foreach(widget, m_selectedWidgets)
×
1398
        widget->raise();
×
1399

1400
    m_doc->setModified();
×
1401
}
1402

1403
void VirtualConsole::slotStackingLower()
×
1404
{
1405
    Q_ASSERT(contents() != NULL);
×
1406

1407
    if (m_selectedWidgets.isEmpty() == true)
×
1408
        return;
×
1409

1410
    VCWidget* widget;
1411
    foreach(widget, m_selectedWidgets)
×
1412
        widget->lower();
×
1413

1414
    m_doc->setModified();
×
1415
}
1416

1417
/*****************************************************************************
1418
 * Frame menu callbacks
1419
 *****************************************************************************/
1420

1421
void VirtualConsole::slotFrameSunken()
×
1422
{
1423
    Q_ASSERT(contents() != NULL);
×
1424

1425
    if (m_selectedWidgets.isEmpty() == true)
×
1426
        return;
×
1427

1428
    VCWidget* widget;
1429
    foreach(widget, m_selectedWidgets)
×
1430
        widget->setFrameStyle(KVCFrameStyleSunken);
×
1431
}
1432

1433
void VirtualConsole::slotFrameRaised()
×
1434
{
1435
    Q_ASSERT(contents() != NULL);
×
1436

1437
    if (m_selectedWidgets.isEmpty() == true)
×
1438
        return;
×
1439

1440
    VCWidget* widget;
1441
    foreach(widget, m_selectedWidgets)
×
1442
        widget->setFrameStyle(KVCFrameStyleRaised);
×
1443
}
1444

1445
void VirtualConsole::slotFrameNone()
×
1446
{
1447
    Q_ASSERT(contents() != NULL);
×
1448

1449
    if (m_selectedWidgets.isEmpty() == true)
×
1450
        return;
×
1451

1452
    VCWidget* widget;
1453
    foreach(widget, m_selectedWidgets)
×
1454
        widget->setFrameStyle(KVCFrameStyleNone);
×
1455
}
1456

1457
/*****************************************************************************
1458
 * Dock area
1459
 *****************************************************************************/
1460

1461
VCDockArea* VirtualConsole::dockArea() const
×
1462
{
1463
    return m_dockArea;
×
1464
}
1465

1466
void VirtualConsole::initDockArea()
76✔
1467
{
1468
    if (m_dockArea != NULL)
76✔
1469
        delete m_dockArea;
×
1470

1471
    m_dockArea = new VCDockArea(this, m_doc->inputOutputMap());
76✔
1472
    m_dockArea->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding);
76✔
1473

1474
    // Add the dock area into the master horizontal layout
1475
    layout()->addWidget(m_dockArea);
76✔
1476

1477
    /* Show the dock area by default */
1478
    m_dockArea->show();
76✔
1479
}
76✔
1480

1481
/*****************************************************************************
1482
 * Contents
1483
 *****************************************************************************/
1484

1485
VCFrame* VirtualConsole::contents() const
787✔
1486
{
1487
    return m_contents;
787✔
1488
}
1489

1490
void VirtualConsole::resetContents()
76✔
1491
{
1492
    if (m_contents != NULL)
76✔
1493
        delete m_contents;
×
1494

1495
    Q_ASSERT(m_scrollArea != NULL);
76✔
1496
    m_contents = new VCFrame(m_scrollArea, m_doc);
76✔
1497
    m_contents->setFrameStyle(0);
76✔
1498

1499
    // Get virtual console size from properties
1500
    QSize size(m_properties.size());
76✔
1501
    contents()->resize(size);
76✔
1502
    contents()->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
76✔
1503
    m_scrollArea->setWidget(contents());
76✔
1504

1505
    /* Disconnect old key handlers to prevent duplicates */
1506
    disconnect(this, SIGNAL(keyPressed(const QKeySequence&)),
152✔
1507
               contents(), SLOT(slotKeyPressed(const QKeySequence&)));
76✔
1508
    disconnect(this, SIGNAL(keyReleased(const QKeySequence&)),
152✔
1509
               contents(), SLOT(slotKeyReleased(const QKeySequence&)));
76✔
1510

1511
    /* Connect new key handlers */
1512
    connect(this, SIGNAL(keyPressed(const QKeySequence&)),
152✔
1513
            contents(), SLOT(slotKeyPressed(const QKeySequence&)));
76✔
1514
    connect(this, SIGNAL(keyReleased(const QKeySequence&)),
152✔
1515
            contents(), SLOT(slotKeyReleased(const QKeySequence&)));
76✔
1516

1517
    /* Make the contents area take up all available space */
1518
    contents()->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
76✔
1519

1520
    m_clipboard.clear();
76✔
1521
    m_selectedWidgets.clear();
76✔
1522
    m_latestWidgetId = 0;
76✔
1523
    m_widgetsMap.clear();
76✔
1524

1525
    /* Update actions' enabled status */
1526
    updateActions();
76✔
1527

1528
    /* Reset all properties but size */
1529
    m_properties.setGrandMasterChannelMode(GrandMaster::Intensity);
76✔
1530
    m_properties.setGrandMasterValueMode(GrandMaster::Reduce);
76✔
1531
    m_properties.setGrandMasterInputSource(InputOutputMap::invalidUniverse(), QLCChannel::invalid());
76✔
1532
}
76✔
1533

1534
void VirtualConsole::addWidgetInMap(VCWidget* widget)
1✔
1535
{
1536
    // Valid ID ?
1537
    if (widget->id() != VCWidget::invalidId())
1✔
1538
    {
1539
        // Maybe we don't know this widget yet
1540
        if (!m_widgetsMap.contains(widget->id()))
×
1541
        {
1542
            m_widgetsMap.insert(widget->id(), widget);
×
1543
            return;
×
1544
        }
1545

1546
        // Maybe we already know this widget
1547
        if (m_widgetsMap[widget->id()] == widget)
×
1548
        {
1549
            qDebug() << Q_FUNC_INFO << "widget" << widget->id() << "already in map";
×
1550
            return;
×
1551
        }
1552

1553
        // This widget id conflicts with another one we have to change it.
1554
        qDebug() << Q_FUNC_INFO << "widget id" << widget->id() << "conflicts, creating a new ID";
×
1555
    }
1556

1557
    quint32 wid = newWidgetId();
1✔
1558
    Q_ASSERT(!m_widgetsMap.contains(wid));
1✔
1559
    qDebug() << Q_FUNC_INFO << "id=" << wid;
1✔
1560
    widget->setID(wid);
1✔
1561
    m_widgetsMap.insert(wid, widget);
1✔
1562
}
1563

1564
void VirtualConsole::setupWidget(VCWidget *widget, VCWidget *parent)
×
1565
{
1566
    Q_ASSERT(widget != NULL);
×
1567
    Q_ASSERT(parent != NULL);
×
1568

1569
    addWidgetInMap(widget);
×
1570
    connectWidgetToParent(widget, parent);
×
1571
    widget->show();
×
1572
    widget->move(parent->lastClickPoint());
×
1573
    clearWidgetSelection();
×
1574
    setWidgetSelected(widget, true);
×
1575
}
×
1576

1577
VCWidget *VirtualConsole::widget(quint32 id)
×
1578
{
1579
    if (id == VCWidget::invalidId())
×
1580
        return NULL;
×
1581

1582
    return m_widgetsMap.value(id, NULL);
×
1583
}
1584

1585
void VirtualConsole::initContents()
76✔
1586
{
1587
    Q_ASSERT(layout() != NULL);
76✔
1588

1589
    m_scrollArea = new QScrollArea(this);
76✔
1590
    m_contentsLayout->addWidget(m_scrollArea);
76✔
1591
    m_scrollArea->setAlignment(Qt::AlignCenter);
76✔
1592
    m_scrollArea->setWidgetResizable(false);
76✔
1593

1594
    resetContents();
76✔
1595
}
76✔
1596

1597
/*****************************************************************************
1598
 * Key press handler
1599
 *****************************************************************************/
1600

1601
void VirtualConsole::keyPressEvent(QKeyEvent* event)
×
1602
{
1603
    if (event->isAutoRepeat() == true)
×
1604
    {
1605
        event->ignore();
×
1606
        return;
×
1607
    }
1608

1609
    QKeySequence seq(event->key() | (event->modifiers() & ~Qt::ControlModifier));
×
1610
    emit keyPressed(seq);
×
1611

1612
    event->accept();
×
1613
}
1614

1615
void VirtualConsole::keyReleaseEvent(QKeyEvent* event)
×
1616
{
1617
    if (event->isAutoRepeat() == true)
×
1618
    {
1619
        event->ignore();
×
1620
        return;
×
1621
    }
1622

1623
    QKeySequence seq(event->key() | event->modifiers());
×
1624
    emit keyReleased(seq);
×
1625

1626
    event->accept();
×
1627
}
1628

1629
/*****************************************************************************
1630
 * Main application mode
1631
 *****************************************************************************/
1632

1633
void VirtualConsole::toggleLiveEdit()
×
1634
{
1635
    // No live edit in Design Mode
1636
    Q_ASSERT(m_doc->mode() == Doc::Operate);
×
1637

1638
    if (m_liveEdit)
×
1639
    { // live edit was on, disable live edit
1640
        m_liveEdit = false;
×
1641
        disableEdit();
×
1642
    }
1643
    else
1644
    { // live edit was off, enable live edit
1645
        m_liveEdit = true;
×
1646
        enableEdit();
×
1647
    }
1648

1649
    // inform the widgets of the live edit status
1650
    QHash<quint32, VCWidget*>::iterator widgetIt = m_widgetsMap.begin();
×
1651
    while (widgetIt != m_widgetsMap.end())
×
1652
    {
1653
        VCWidget* widget = widgetIt.value();
×
1654
        widget->setLiveEdit(m_liveEdit);
×
1655
        ++widgetIt;
×
1656
    }
1657
    m_contents->setLiveEdit(m_liveEdit);
×
1658
}
×
1659

1660
bool VirtualConsole::liveEdit() const
177✔
1661
{
1662
    return m_liveEdit;
177✔
1663
}
1664

1665
void VirtualConsole::enableEdit()
80✔
1666
{
1667
    // Allow editing and adding in design mode
1668
    m_toolsSettingsAction->setEnabled(true);
80✔
1669
    m_editActionGroup->setEnabled(true);
80✔
1670
    m_addActionGroup->setEnabled(true);
80✔
1671
    m_bgActionGroup->setEnabled(true);
80✔
1672
    m_fgActionGroup->setEnabled(true);
80✔
1673
    m_fontActionGroup->setEnabled(true);
80✔
1674
    m_frameActionGroup->setEnabled(true);
80✔
1675
    m_stackingActionGroup->setEnabled(true);
80✔
1676

1677
    // Set action shortcuts for design mode
1678
    m_addButtonAction->setShortcut(QKeySequence("CTRL+SHIFT+B"));
80✔
1679
    m_addButtonMatrixAction->setShortcut(QKeySequence("CTRL+SHIFT+M"));
80✔
1680
    m_addSliderAction->setShortcut(QKeySequence("CTRL+SHIFT+S"));
80✔
1681
    m_addSliderMatrixAction->setShortcut(QKeySequence("CTRL+SHIFT+I"));
80✔
1682
    m_addKnobAction->setShortcut(QKeySequence("CTRL+SHIFT+K"));
80✔
1683
    m_addSpeedDialAction->setShortcut(QKeySequence("CTRL+SHIFT+D"));
80✔
1684
    m_addXYPadAction->setShortcut(QKeySequence("CTRL+SHIFT+X"));
80✔
1685
    m_addCueListAction->setShortcut(QKeySequence("CTRL+SHIFT+C"));
80✔
1686
    m_addFrameAction->setShortcut(QKeySequence("CTRL+SHIFT+F"));
80✔
1687
    m_addSoloFrameAction->setShortcut(QKeySequence("CTRL+SHIFT+O"));
80✔
1688
    m_addLabelAction->setShortcut(QKeySequence("CTRL+SHIFT+L"));
80✔
1689
    m_addAudioTriggersAction->setShortcut(QKeySequence("CTRL+SHIFT+A"));
80✔
1690
    m_addClockAction->setShortcut(QKeySequence("CTRL+SHIFT+T"));
80✔
1691
    m_addAnimationAction->setShortcut(QKeySequence("CTRL+SHIFT+R"));
80✔
1692

1693
    m_editCutAction->setShortcut(QKeySequence("CTRL+X"));
80✔
1694
    m_editCopyAction->setShortcut(QKeySequence("CTRL+C"));
80✔
1695
    m_editPasteAction->setShortcut(QKeySequence("CTRL+V"));
80✔
1696
    m_editDeleteAction->setShortcut(QKeySequence("Delete"));
80✔
1697
    m_editPropertiesAction->setShortcut(QKeySequence("CTRL+E"));
80✔
1698

1699
    m_bgColorAction->setShortcut(QKeySequence("SHIFT+B"));
80✔
1700
    m_bgImageAction->setShortcut(QKeySequence("SHIFT+I"));
80✔
1701
    m_bgDefaultAction->setShortcut(QKeySequence("SHIFT+ALT+B"));
80✔
1702
    m_fgColorAction->setShortcut(QKeySequence("SHIFT+F"));
80✔
1703
    m_fgDefaultAction->setShortcut(QKeySequence("SHIFT+ALT+F"));
80✔
1704
    m_fontAction->setShortcut(QKeySequence("SHIFT+O"));
80✔
1705
    m_resetFontAction->setShortcut(QKeySequence("SHIFT+ALT+O"));
80✔
1706
    m_frameSunkenAction->setShortcut(QKeySequence("SHIFT+S"));
80✔
1707
    m_frameRaisedAction->setShortcut(QKeySequence("SHIFT+R"));
80✔
1708
    m_frameNoneAction->setShortcut(QKeySequence("SHIFT+ALT+S"));
80✔
1709

1710
    m_stackingRaiseAction->setShortcut(QKeySequence("SHIFT+UP"));
80✔
1711
    m_stackingLowerAction->setShortcut(QKeySequence("SHIFT+DOWN"));
80✔
1712

1713
    // Show toolbar
1714
    m_toolbar->show();
80✔
1715
}
80✔
1716

1717
void VirtualConsole::disableEdit()
15✔
1718
{
1719
    // Don't allow editing or adding in operate mode
1720
    m_toolsSettingsAction->setEnabled(false);
15✔
1721
    m_editActionGroup->setEnabled(false);
15✔
1722
    m_addActionGroup->setEnabled(false);
15✔
1723
    m_bgActionGroup->setEnabled(false);
15✔
1724
    m_fgActionGroup->setEnabled(false);
15✔
1725
    m_fontActionGroup->setEnabled(false);
15✔
1726
    m_frameActionGroup->setEnabled(false);
15✔
1727
    m_stackingActionGroup->setEnabled(false);
15✔
1728

1729
    // Disable action shortcuts in operate mode
1730
    m_addButtonAction->setShortcut(QKeySequence());
15✔
1731
    m_addButtonMatrixAction->setShortcut(QKeySequence());
15✔
1732
    m_addSliderAction->setShortcut(QKeySequence());
15✔
1733
    m_addSliderMatrixAction->setShortcut(QKeySequence());
15✔
1734
    m_addKnobAction->setShortcut(QKeySequence());
15✔
1735
    m_addSpeedDialAction->setShortcut(QKeySequence());
15✔
1736
    m_addXYPadAction->setShortcut(QKeySequence());
15✔
1737
    m_addCueListAction->setShortcut(QKeySequence());
15✔
1738
    m_addFrameAction->setShortcut(QKeySequence());
15✔
1739
    m_addSoloFrameAction->setShortcut(QKeySequence());
15✔
1740
    m_addLabelAction->setShortcut(QKeySequence());
15✔
1741
    m_addAudioTriggersAction->setShortcut(QKeySequence());
15✔
1742
    m_addClockAction->setShortcut(QKeySequence());
15✔
1743
    m_addAnimationAction->setShortcut(QKeySequence());
15✔
1744

1745
    m_editCutAction->setShortcut(QKeySequence());
15✔
1746
    m_editCopyAction->setShortcut(QKeySequence());
15✔
1747
    m_editPasteAction->setShortcut(QKeySequence());
15✔
1748
    m_editDeleteAction->setShortcut(QKeySequence());
15✔
1749
    m_editPropertiesAction->setShortcut(QKeySequence());
15✔
1750

1751
    m_bgColorAction->setShortcut(QKeySequence());
15✔
1752
    m_bgImageAction->setShortcut(QKeySequence());
15✔
1753
    m_bgDefaultAction->setShortcut(QKeySequence());
15✔
1754
    m_fgColorAction->setShortcut(QKeySequence());
15✔
1755
    m_fgDefaultAction->setShortcut(QKeySequence());
15✔
1756
    m_fontAction->setShortcut(QKeySequence());
15✔
1757
    m_resetFontAction->setShortcut(QKeySequence());
15✔
1758
    m_frameSunkenAction->setShortcut(QKeySequence());
15✔
1759
    m_frameRaisedAction->setShortcut(QKeySequence());
15✔
1760
    m_frameNoneAction->setShortcut(QKeySequence());
15✔
1761

1762
    m_stackingRaiseAction->setShortcut(QKeySequence());
15✔
1763
    m_stackingLowerAction->setShortcut(QKeySequence());
15✔
1764

1765
    // Hide toolbar; there's nothing usable there in operate mode
1766
    m_toolbar->hide();
15✔
1767

1768
    // Make sure the virtual console contents has the focus.
1769
    // Without this, key combinations don't work unless
1770
    // the user clicks on some VC area
1771
    m_contents->setFocus();
15✔
1772
}
15✔
1773

1774
void VirtualConsole::slotModeChanged(Doc::Mode mode)
95✔
1775
{
1776
    if (mode == Doc::Operate)
95✔
1777
    { // Switch from Design mode to Operate mode
1778
        // Hide edit tools
1779
        disableEdit();
15✔
1780
    }
1781
    else
1782
    { // Switch from Operate mode to Design mode
1783
        if (m_liveEdit)
80✔
1784
        {
1785
            // Edit tools already shown,
1786
            // inform the widgets that we are out of live edit mode
1787
            m_liveEdit = false;
×
1788
            QHash<quint32, VCWidget*>::iterator widgetIt = m_widgetsMap.begin();
×
1789
            while (widgetIt != m_widgetsMap.end())
×
1790
            {
1791
                VCWidget* widget = widgetIt.value();
×
1792
                widget->cancelLiveEdit();
×
1793
                ++widgetIt;
×
1794
            }
1795
            m_contents->cancelLiveEdit();
×
1796
        }
1797
        else
1798
        {
1799
            // Show edit tools
1800
            enableEdit();
80✔
1801
        }
1802
    }
1803
}
95✔
1804

1805
/*****************************************************************************
1806
 * Load & Save
1807
 *****************************************************************************/
1808

1809
bool VirtualConsole::loadXML(QXmlStreamReader &root)
×
1810
{
1811
    if (root.name() != KXMLQLCVirtualConsole)
×
1812
    {
1813
        qWarning() << Q_FUNC_INFO << "Virtual Console node not found";
×
1814
        return false;
×
1815
    }
1816

1817
    while (root.readNextStartElement())
×
1818
    {
1819
        //qDebug() << "VC tag:" << root.name();
1820
        if (root.name() == KXMLQLCVCProperties)
×
1821
        {
1822
            /* Properties */
1823
            m_properties.loadXML(root);
×
1824
            QSize size(m_properties.size());
×
1825
            contents()->resize(size);
×
1826
            contents()->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
×
1827
        }
1828
        else if (root.name() == KXMLQLCVCFrame)
×
1829
        {
1830
            /* Contents */
1831
            Q_ASSERT(m_contents != NULL);
×
1832
            m_contents->loadXML(root);
×
1833
        }
1834
        else
1835
        {
1836
            qWarning() << Q_FUNC_INFO << "Unknown Virtual Console tag"
×
1837
                       << root.name().toString();
×
1838
            root.skipCurrentElement();
×
1839
        }
1840
    }
1841

1842
    return true;
×
1843
}
1844

1845
bool VirtualConsole::saveXML(QXmlStreamWriter *doc)
×
1846
{
1847
    Q_ASSERT(doc != NULL);
×
1848

1849
    /* Virtual Console entry */
1850
    doc->writeStartElement(KXMLQLCVirtualConsole);
×
1851

1852
    /* Contents */
1853
    Q_ASSERT(m_contents != NULL);
×
1854
    m_contents->saveXML(doc);
×
1855

1856
    /* Properties */
1857
    m_properties.saveXML(doc);
×
1858

1859
    /* End the <VirtualConsole> tag */
1860
    doc->writeEndElement();
×
1861

1862
    return true;
×
1863
}
1864

1865
QList<VCWidget *> VirtualConsole::getChildren(VCWidget *obj)
×
1866
{
1867
    QList<VCWidget *> list;
×
1868
    if (obj == NULL)
×
1869
        return list;
×
1870
    QListIterator <VCWidget*> it(obj->findChildren<VCWidget*>());
×
1871
    while (it.hasNext() == true)
×
1872
    {
1873
        VCWidget* child = it.next();
×
1874
        list.append(child);
×
1875
        list.append(getChildren(child));
×
1876
    }
1877
    return list;
×
1878
}
1879

1880
void VirtualConsole::postLoad()
×
1881
{
1882
    m_contents->postLoad();
×
1883

1884
    /* apply GM values
1885
      this should probably be placed in another place, but at the moment m_properties
1886
      is just loaded in VirtualConsole */
1887
    m_doc->inputOutputMap()->setGrandMasterValue(255);
×
1888
    m_doc->inputOutputMap()->setGrandMasterValueMode(m_properties.grandMasterValueMode());
×
1889
    m_doc->inputOutputMap()->setGrandMasterChannelMode(m_properties.grandMasterChannelMode());
×
1890
    
1891
    /** Setting flash property values in the doc class. As described above consider placing it somewhere else. */
1892
    m_doc->setFlashOverrides(m_properties.flashOverrides());
×
1893
    m_doc->setFlashForceLTP(m_properties.flashForceLTP());
×
1894

1895
    /* Go through widgets, check IDs and register */
1896
    /* widgets to the map */
1897
    /* This code is the same as the one in addWidgetInMap() */
1898
    /* We have to repeat it to limit conflicts if */
1899
    /* one widget was not saved with a valid ID, */
1900
    /* as addWidgetInMap ensures the widget WILL be added */
1901
    QList<VCWidget *> widgetsList = getChildren(m_contents);
×
1902
    QList<VCWidget *> invalidWidgetsList;
×
1903
    foreach (VCWidget *widget, widgetsList)
×
1904
    {
1905
        quint32 wid = widget->id();
×
1906
        if (wid != VCWidget::invalidId())
×
1907
        {
1908
            if (!m_widgetsMap.contains(wid))
×
1909
                m_widgetsMap.insert(wid, widget);
×
1910
            else if (m_widgetsMap[wid] != widget)
×
1911
                invalidWidgetsList.append(widget);
×
1912
        }
1913
        else
1914
            invalidWidgetsList.append(widget);
×
1915
    }
1916
    foreach (VCWidget *widget, invalidWidgetsList)
×
1917
        addWidgetInMap(widget);
×
1918

1919
    m_contents->setFocus();
×
1920

1921
    emit loaded();
×
1922
}
×
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