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

mcallegari / qlcplus / 13633248611

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

push

github

web-flow
actions: add chrpath to profile

14689 of 46089 relevant lines covered (31.87%)

26426.11 hits per line

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

50.4
/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 "functionwizard.h"
60
#include "doc.h"
61

62
#define SETTINGS_VC_SIZE "virtualconsole/size"
63

64
VirtualConsole* VirtualConsole::s_instance = NULL;
65

66
/****************************************************************************
67
 * Initialization
68
 ****************************************************************************/
69

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

75
    , m_editAction(EditNone)
76✔
76
    , m_toolbar(NULL)
76✔
77

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

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

101
    , m_toolsSettingsAction(NULL)
76✔
102
    , m_functionWizardAction(NULL)
76✔
103

104
    , m_editCutAction(NULL)
76✔
105
    , m_editCopyAction(NULL)
76✔
106
    , m_editPasteAction(NULL)
76✔
107
    , m_editDeleteAction(NULL)
76✔
108
    , m_editPropertiesAction(NULL)
76✔
109
    , m_editRenameAction(NULL)
76✔
110

111
    , m_bgColorAction(NULL)
76✔
112
    , m_bgImageAction(NULL)
76✔
113
    , m_bgDefaultAction(NULL)
76✔
114

115
    , m_fgColorAction(NULL)
76✔
116
    , m_fgDefaultAction(NULL)
76✔
117

118
    , m_fontAction(NULL)
76✔
119
    , m_resetFontAction(NULL)
76✔
120

121
    , m_frameSunkenAction(NULL)
76✔
122
    , m_frameRaisedAction(NULL)
76✔
123
    , m_frameNoneAction(NULL)
76✔
124

125
    , m_stackingRaiseAction(NULL)
76✔
126
    , m_stackingLowerAction(NULL)
76✔
127

128
    , m_customMenu(NULL)
76✔
129
    , m_editMenu(NULL)
76✔
130
    , m_addMenu(NULL)
76✔
131

132
    , m_dockArea(NULL)
76✔
133
    , m_contentsLayout(NULL)
76✔
134
    , m_scrollArea(NULL)
76✔
135
    , m_contents(NULL)
76✔
136

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

142
    Q_ASSERT(doc != NULL);
143

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

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

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

160
    // Use the initial mode
161
    slotModeChanged(m_doc->mode());
76✔
162

163
    // Nothing is selected
164
    updateActions();
76✔
165
}
76✔
166

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

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

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

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

192
    return m_latestWidgetId;
1✔
193
}
194

195
/*****************************************************************************
196
 * Properties
197
 *****************************************************************************/
198

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

204
/*****************************************************************************
205
 * Selected widget
206
 *****************************************************************************/
207

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

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

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

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

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

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

241
    /* Enable or disable actions */
242
    updateActions();
4✔
243
}
4✔
244

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

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

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

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

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

269
    /* Enable or disable actions */
270
    updateActions();
6✔
271
}
6✔
272

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

281
/*****************************************************************************
282
 * Actions, menu- and toolbar
283
 *****************************************************************************/
284

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

370
    m_functionWizardAction = new QAction(QIcon(":/wizard.png"), tr("VC Fixture Widget Wizard"), this);
152✔
371
    connect(m_functionWizardAction, SIGNAL(triggered(bool)), this, SLOT(slotWizard()));
76✔
372

373
    /* Edit menu actions */
374
    m_editCutAction = new QAction(QIcon(":/editcut.png"), tr("Cut"), this);
152✔
375
    connect(m_editCutAction, SIGNAL(triggered(bool)), this, SLOT(slotEditCut()));
76✔
376

377
    m_editCopyAction = new QAction(QIcon(":/editcopy.png"), tr("Copy"), this);
152✔
378
    connect(m_editCopyAction, SIGNAL(triggered(bool)), this, SLOT(slotEditCopy()));
76✔
379

380
    m_editPasteAction = new QAction(QIcon(":/editpaste.png"), tr("Paste"), this);
152✔
381
    m_editPasteAction->setEnabled(false);
76✔
382
    connect(m_editPasteAction, SIGNAL(triggered(bool)), this, SLOT(slotEditPaste()));
76✔
383

384
    m_editDeleteAction = new QAction(QIcon(":/editdelete.png"), tr("Delete"), this);
152✔
385
    connect(m_editDeleteAction, SIGNAL(triggered(bool)), this, SLOT(slotEditDelete()));
76✔
386

387
    m_editPropertiesAction = new QAction(QIcon(":/edit.png"), tr("Widget Properties"), this);
152✔
388
    connect(m_editPropertiesAction, SIGNAL(triggered(bool)), this, SLOT(slotEditProperties()));
76✔
389

390
    m_editRenameAction = new QAction(QIcon(":/editclear.png"), tr("Rename Widget"), this);
152✔
391
    connect(m_editRenameAction, SIGNAL(triggered(bool)), this, SLOT(slotEditRename()));
76✔
392

393
    /* Put edit actions under the same group */
394
    m_editActionGroup = new QActionGroup(this);
76✔
395
    m_editActionGroup->setExclusive(false);
76✔
396
    m_editActionGroup->addAction(m_editCutAction);
76✔
397
    m_editActionGroup->addAction(m_editCopyAction);
76✔
398
    m_editActionGroup->addAction(m_editPasteAction);
76✔
399
    m_editActionGroup->addAction(m_editDeleteAction);
76✔
400
    m_editActionGroup->addAction(m_editPropertiesAction);
76✔
401
    m_editActionGroup->addAction(m_editRenameAction);
76✔
402

403
    /* Background menu actions */
404
    m_bgColorAction = new QAction(QIcon(":/color.png"), tr("Background Color"), this);
152✔
405
    connect(m_bgColorAction, SIGNAL(triggered(bool)), this, SLOT(slotBackgroundColor()));
76✔
406

407
    m_bgImageAction = new QAction(QIcon(":/image.png"), tr("Background Image"), this);
152✔
408
    connect(m_bgImageAction, SIGNAL(triggered(bool)), this, SLOT(slotBackgroundImage()));
76✔
409

410
    m_bgDefaultAction = new QAction(QIcon(":/undo.png"), tr("Default"), this);
152✔
411
    connect(m_bgDefaultAction, SIGNAL(triggered(bool)), this, SLOT(slotBackgroundNone()));
76✔
412

413
    /* Put BG actions under the same group */
414
    m_bgActionGroup = new QActionGroup(this);
76✔
415
    m_bgActionGroup->setExclusive(false);
76✔
416
    m_bgActionGroup->addAction(m_bgColorAction);
76✔
417
    m_bgActionGroup->addAction(m_bgImageAction);
76✔
418
    m_bgActionGroup->addAction(m_bgDefaultAction);
76✔
419

420
    /* Foreground menu actions */
421
    m_fgColorAction = new QAction(QIcon(":/fontcolor.png"), tr("Font Colour"), this);
152✔
422
    connect(m_fgColorAction, SIGNAL(triggered(bool)), this, SLOT(slotForegroundColor()));
76✔
423

424
    m_fgDefaultAction = new QAction(QIcon(":/undo.png"), tr("Default"), this);
152✔
425
    connect(m_fgDefaultAction, SIGNAL(triggered(bool)), this, SLOT(slotForegroundNone()));
76✔
426

427
    /* Put FG actions under the same group */
428
    m_fgActionGroup = new QActionGroup(this);
76✔
429
    m_fgActionGroup->setExclusive(false);
76✔
430
    m_fgActionGroup->addAction(m_fgColorAction);
76✔
431
    m_fgActionGroup->addAction(m_fgDefaultAction);
76✔
432

433
    /* Font menu actions */
434
    m_fontAction = new QAction(QIcon(":/fonts.png"), tr("Font"), this);
152✔
435
    connect(m_fontAction, SIGNAL(triggered(bool)), this, SLOT(slotFont()));
76✔
436

437
    m_resetFontAction = new QAction(QIcon(":/undo.png"), tr("Default"), this);
152✔
438
    connect(m_resetFontAction, SIGNAL(triggered(bool)), this, SLOT(slotResetFont()));
76✔
439

440
    /* Put font actions under the same group */
441
    m_fontActionGroup = new QActionGroup(this);
76✔
442
    m_fontActionGroup->setExclusive(false);
76✔
443
    m_fontActionGroup->addAction(m_fontAction);
76✔
444
    m_fontActionGroup->addAction(m_resetFontAction);
76✔
445

446
    /* Frame menu actions */
447
    m_frameSunkenAction = new QAction(QIcon(":/framesunken.png"), tr("Sunken"), this);
152✔
448
    connect(m_frameSunkenAction, SIGNAL(triggered(bool)), this, SLOT(slotFrameSunken()));
76✔
449

450
    m_frameRaisedAction = new QAction(QIcon(":/frameraised.png"), tr("Raised"), this);
152✔
451
    connect(m_frameRaisedAction, SIGNAL(triggered(bool)), this, SLOT(slotFrameRaised()));
76✔
452

453
    m_frameNoneAction = new QAction(QIcon(":/framenone.png"), tr("None"), this);
152✔
454
    connect(m_frameNoneAction, SIGNAL(triggered(bool)), this, SLOT(slotFrameNone()));
76✔
455

456
    /* Put frame actions under the same group */
457
    m_frameActionGroup = new QActionGroup(this);
76✔
458
    m_frameActionGroup->setExclusive(false);
76✔
459
    m_frameActionGroup->addAction(m_frameRaisedAction);
76✔
460
    m_frameActionGroup->addAction(m_frameSunkenAction);
76✔
461
    m_frameActionGroup->addAction(m_frameNoneAction);
76✔
462

463
    /* Stacking menu actions */
464
    m_stackingRaiseAction = new QAction(QIcon(":/up.png"), tr("Bring to front"), this);
152✔
465
    connect(m_stackingRaiseAction, SIGNAL(triggered(bool)), this, SLOT(slotStackingRaise()));
76✔
466

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

470
    /* Put stacking actions under the same group */
471
    m_stackingActionGroup = new QActionGroup(this);
76✔
472
    m_stackingActionGroup->setExclusive(false);
76✔
473
    m_stackingActionGroup->addAction(m_stackingRaiseAction);
76✔
474
    m_stackingActionGroup->addAction(m_stackingLowerAction);
76✔
475
}
76✔
476

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

500
    /* Edit menu */
501
    m_editMenu = new QMenu(this);
76✔
502
    m_editMenu->setTitle(tr("&Edit"));
76✔
503
    m_editMenu->addAction(m_editCutAction);
76✔
504
    m_editMenu->addAction(m_editCopyAction);
76✔
505
    m_editMenu->addAction(m_editPasteAction);
76✔
506
    m_editMenu->addAction(m_editDeleteAction);
76✔
507
    m_editMenu->addSeparator();
76✔
508
    m_editMenu->addAction(m_editPropertiesAction);
76✔
509
    m_editMenu->addAction(m_editRenameAction);
76✔
510
    m_editMenu->addSeparator();
76✔
511

512
    /* Background Menu */
513
    QMenu* bgMenu = new QMenu(m_editMenu);
76✔
514
    bgMenu->setTitle(tr("&Background"));
76✔
515
    m_editMenu->addMenu(bgMenu);
76✔
516
    bgMenu->addAction(m_bgColorAction);
76✔
517
    bgMenu->addAction(m_bgImageAction);
76✔
518
    bgMenu->addAction(m_bgDefaultAction);
76✔
519

520
    /* Foreground menu */
521
    QMenu* fgMenu = new QMenu(m_editMenu);
76✔
522
    fgMenu->setTitle(tr("&Foreground"));
76✔
523
    m_editMenu->addMenu(fgMenu);
76✔
524
    fgMenu->addAction(m_fgColorAction);
76✔
525
    fgMenu->addAction(m_fgDefaultAction);
76✔
526

527
    /* Font menu */
528
    QMenu* fontMenu = new QMenu(m_editMenu);
76✔
529
    fontMenu->setTitle(tr("F&ont"));
76✔
530
    m_editMenu->addMenu(fontMenu);
76✔
531
    fontMenu->addAction(m_fontAction);
76✔
532
    fontMenu->addAction(m_resetFontAction);
76✔
533

534
    /* Frame menu */
535
    QMenu* frameMenu = new QMenu(m_editMenu);
76✔
536
    frameMenu->setTitle(tr("F&rame"));
76✔
537
    m_editMenu->addMenu(frameMenu);
76✔
538
    frameMenu->addAction(m_frameSunkenAction);
76✔
539
    frameMenu->addAction(m_frameRaisedAction);
76✔
540
    frameMenu->addAction(m_frameNoneAction);
76✔
541

542
    /* Stacking order menu */
543
    QMenu* stackMenu = new QMenu(m_editMenu);
76✔
544
    stackMenu->setTitle(tr("Stacking &order"));
76✔
545
    m_editMenu->addMenu(stackMenu);
76✔
546
    stackMenu->addAction(m_stackingRaiseAction);
76✔
547
    stackMenu->addAction(m_stackingLowerAction);
76✔
548

549
    /* Add a separator that separates the common edit items from a custom
550
       widget menu that gets appended to the edit menu when a selected
551
       widget provides one. */
552
    m_editMenu->addSeparator();
76✔
553

554
    /* Toolbar */
555
    m_toolbar = new QToolBar(this);
76✔
556
    m_toolbar->setIconSize(QSize(26,26));
76✔
557
    m_contentsLayout->addWidget(m_toolbar);
76✔
558

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

595
void VirtualConsole::updateCustomMenu()
10✔
596
{
597
    /* Get rid of the custom menu, but delete it later because this might
598
       be called from the very menu that is being deleted. */
599
    if (m_customMenu != NULL)
10✔
600
    {
601
        delete m_customMenu;
6✔
602
        m_customMenu = NULL;
6✔
603
    }
604

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

623
void VirtualConsole::updateActions()
162✔
624
{
625
    /* When selected widgets is empty, all actions go to main draw area. */
626
    if (m_selectedWidgets.isEmpty() == true)
162✔
627
    {
628
        /* Enable widget additions to draw area */
629
        m_addActionGroup->setEnabled(true);
158✔
630

631
        /* Disable edit actions that can't be allowed for draw area */
632
        m_editCutAction->setEnabled(false);
158✔
633
        m_editCopyAction->setEnabled(false);
158✔
634
        m_editDeleteAction->setEnabled(false);
158✔
635
        m_editRenameAction->setEnabled(false);
158✔
636
        m_editPropertiesAction->setEnabled(false);
158✔
637

638
        /* All the rest are disabled for draw area, except BG & font */
639
        m_frameActionGroup->setEnabled(false);
158✔
640
        m_stackingActionGroup->setEnabled(false);
158✔
641

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

657
        /* Enable all common properties */
658
        m_bgActionGroup->setEnabled(true);
4✔
659
        m_fgActionGroup->setEnabled(true);
4✔
660
        m_fontActionGroup->setEnabled(true);
4✔
661
        m_frameActionGroup->setEnabled(true);
4✔
662
        m_stackingActionGroup->setEnabled(true);
4✔
663

664
        /* Check, whether the last selected widget can hold children */
665
        if (m_selectedWidgets.last()->allowChildren() == true)
4✔
666
        {
667
            /* Enable paste for widgets that can hold children */
668
            if (m_clipboard.isEmpty() == true)
1✔
669
                m_editPasteAction->setEnabled(false);
1✔
670
            else
671
                m_editPasteAction->setEnabled(true);
×
672

673
            /* Enable also new additions */
674
            m_addActionGroup->setEnabled(true);
1✔
675
        }
676
        else
677
        {
678
            /* No pasted children possible */
679
            m_editPasteAction->setEnabled(false);
3✔
680
        }
681
    }
682

683
    if (contents()->children().count() == 0)
162✔
684
        m_latestWidgetId = 0;
156✔
685
}
162✔
686

687
/*****************************************************************************
688
 * Add menu callbacks
689
 *****************************************************************************/
690

691
VCWidget* VirtualConsole::closestParent() const
×
692
{
693
    /* If nothing is selected, return the bottom-most contents frame */
694
    if (m_selectedWidgets.isEmpty() == true)
×
695
        return contents();
×
696

697
    /* Find the next VCWidget in the hierarchy that accepts children */
698
    VCWidget* widget = m_selectedWidgets.last();
×
699
    while (widget != NULL)
×
700
    {
701
        if (widget->allowChildren() == true)
×
702
            return widget;
×
703
        else
704
            widget = qobject_cast<VCWidget*> (widget->parentWidget());
705
    }
706

707
    return NULL;
708
}
709

710
void VirtualConsole::connectWidgetToParent(VCWidget *widget, VCWidget *parent)
×
711
{
712
    if (parent->type() == VCWidget::FrameWidget
×
713
            || parent->type() == VCWidget::SoloFrameWidget)
×
714
    {
715
        VCFrame *frame = qobject_cast<VCFrame *>(parent);
716
        if (frame != NULL)
×
717
        {
718
            widget->setPage(frame->currentPage());
×
719
            frame->addWidgetToPageMap(widget);
×
720
        }
721
    }
722
    else
723
        widget->setPage(0);
×
724

725
    if (widget->type() == VCWidget::SliderWidget)
×
726
    {
727
        VCSlider *slider = qobject_cast<VCSlider *>(widget);
728
        if (slider != NULL)
×
729
        {
730
            connect(slider, SIGNAL(submasterValueChanged(qreal)),
×
731
                    parent, SLOT(slotSubmasterValueChanged(qreal)));
732
        }
733
    }
734
}
×
735

736
void VirtualConsole::disconnectWidgetFromParent(VCWidget *widget, VCWidget *parent)
×
737
{
738
    if (parent->type() == VCWidget::FrameWidget
×
739
            || parent->type() == VCWidget::SoloFrameWidget)
×
740
    {
741
        VCFrame *frame = qobject_cast<VCFrame *>(parent);
742
        if (frame != NULL)
×
743
            frame->removeWidgetFromPageMap(widget);
×
744
    }
745

746
    if (widget->type() == VCWidget::SliderWidget)
×
747
    {
748
        VCSlider *slider = qobject_cast<VCSlider *>(widget);
749
        if (slider != NULL)
×
750
        {
751
            disconnect(slider, SIGNAL(submasterValueChanged(qreal)),
×
752
                       parent, SLOT(slotSubmasterValueChanged(qreal)));
753
        }
754
    }
755
}
×
756

757
void VirtualConsole::slotAddButton()
×
758
{
759
    VCWidget* parent(closestParent());
×
760
    if (parent == NULL)
×
761
        return;
762

763
    VCButton* button = new VCButton(parent, m_doc);
×
764
    setupWidget(button, parent);
×
765
    m_doc->setModified();
×
766
}
767

768
void VirtualConsole::slotAddButtonMatrix()
×
769
{
770
    VCWidget* parent(closestParent());
×
771
    if (parent == NULL)
×
772
        return;
×
773

774
    AddVCButtonMatrix abm(this, m_doc);
×
775
    if (abm.exec() == QDialog::Rejected)
×
776
        return;
777

778
    int h = abm.horizontalCount();
×
779
    int v = abm.verticalCount();
×
780
    int sz = abm.buttonSize();
×
781

782
    VCFrame* frame = NULL;
783
    if (abm.frameStyle() == AddVCButtonMatrix::NormalFrame)
×
784
        frame = new VCFrame(parent, m_doc);
×
785
    else
786
        frame = new VCSoloFrame(parent, m_doc);
×
787
    Q_ASSERT(frame != NULL);
788
    addWidgetInMap(frame);
×
789
    frame->setHeaderVisible(false);
×
790
    connectWidgetToParent(frame, parent);
×
791

792
    // Resize the parent frame to fit the buttons nicely and toggle resizing off
793
    frame->resize(QSize((h * sz) + 20, (v * sz) + 20));
×
794
    frame->setAllowResize(false);
×
795

796
    for (int y = 0; y < v; y++)
×
797
    {
798
        for (int x = 0; x < h; x++)
×
799
        {
800
            VCButton* button = new VCButton(frame, m_doc);
×
801
            Q_ASSERT(button != NULL);
802
            addWidgetInMap(button);
×
803
            connectWidgetToParent(button, frame);
×
804
            button->move(QPoint(10 + (x * sz), 10 + (y * sz)));
×
805
            button->resize(QSize(sz, sz));
×
806
            button->show();
×
807

808
            int index = (y * h) + x;
×
809
            if (index < abm.functions().size())
×
810
            {
811
                quint32 fid = abm.functions().at(index);
×
812
                Function* function = m_doc->function(fid);
×
813
                if (function != NULL)
×
814
                {
815
                    button->setFunction(fid);
×
816
                    button->setCaption(function->name());
×
817
                }
818
            }
819
        }
820
    }
821

822
    // Show the frame after adding buttons to prevent flickering
823
    frame->show();
×
824
    frame->move(parent->lastClickPoint());
×
825
    frame->setAllowChildren(false); // Don't allow more children
×
826
    clearWidgetSelection();
×
827
    setWidgetSelected(frame, true);
×
828
    m_doc->setModified();
×
829
}
×
830

831
void VirtualConsole::slotAddSlider()
×
832
{
833
    VCWidget* parent(closestParent());
×
834
    if (parent == NULL)
×
835
        return;
836

837
    VCSlider* slider = new VCSlider(parent, m_doc);
×
838
    setupWidget(slider, parent);
×
839
    m_doc->setModified();
×
840
}
841

842
void VirtualConsole::slotAddSliderMatrix()
×
843
{
844
    VCWidget* parent(closestParent());
×
845
    if (parent == NULL)
×
846
        return;
×
847

848
    AddVCSliderMatrix avsm(this);
×
849
    if (avsm.exec() == QDialog::Rejected)
×
850
        return;
851

852
    int width = avsm.width();
×
853
    int height = avsm.height();
×
854
    int count = avsm.amount();
×
855

856
    VCFrame* frame = new VCFrame(parent, m_doc);
×
857
    Q_ASSERT(frame != NULL);
858
    addWidgetInMap(frame);
×
859
    frame->setHeaderVisible(false);
×
860
    connectWidgetToParent(frame, parent);
×
861

862
    // Resize the parent frame to fit the sliders nicely
863
    frame->resize(QSize((count * width) + 20, height + 20));
×
864
    frame->setAllowResize(false);
×
865

866
    for (int i = 0; i < count; i++)
×
867
    {
868
        VCSlider* slider = new VCSlider(frame, m_doc);
×
869
        Q_ASSERT(slider != NULL);
870
        addWidgetInMap(slider);
×
871
        connectWidgetToParent(slider, frame);
×
872
        slider->move(QPoint(10 + (width * i), 10));
×
873
        slider->resize(QSize(width, height));
×
874
        slider->show();
×
875
    }
876

877
    // Show the frame after adding buttons to prevent flickering
878
    frame->show();
×
879
    frame->move(parent->lastClickPoint());
×
880
    frame->setAllowChildren(false); // Don't allow more children
×
881
    clearWidgetSelection();
×
882
    setWidgetSelected(frame, true);
×
883
    m_doc->setModified();
×
884
}
×
885

886
void VirtualConsole::slotAddKnob()
×
887
{
888
    VCWidget* parent(closestParent());
×
889
    if (parent == NULL)
×
890
        return;
891

892
    VCSlider* knob = new VCSlider(parent, m_doc);
×
893
    setupWidget(knob, parent);
×
894
    knob->resize(QSize(60, 90));
×
895
    knob->setWidgetStyle(VCSlider::WKnob);
×
896
    knob->setCaption(tr("Knob %1").arg(knob->id()));
×
897
    m_doc->setModified();
×
898
}
899

900
void VirtualConsole::slotAddSpeedDial()
×
901
{
902
    VCWidget* parent(closestParent());
×
903
    if (parent == NULL)
×
904
        return;
905

906
    VCSpeedDial* dial = new VCSpeedDial(parent, m_doc);
×
907
    setupWidget(dial, parent);
×
908
    m_doc->setModified();
×
909
}
910

911
void VirtualConsole::slotAddXYPad()
×
912
{
913
    VCWidget* parent(closestParent());
×
914
    if (parent == NULL)
×
915
        return;
916

917
    VCXYPad* xypad = new VCXYPad(parent, m_doc);
×
918
    setupWidget(xypad, parent);
×
919
    m_doc->setModified();
×
920
}
921

922
void VirtualConsole::slotAddCueList()
×
923
{
924
    VCWidget* parent(closestParent());
×
925
    if (parent == NULL)
×
926
        return;
927

928
    VCCueList* cuelist = new VCCueList(parent, m_doc);
×
929
    setupWidget(cuelist, parent);
×
930
    m_doc->setModified();
×
931
}
932

933
void VirtualConsole::slotAddFrame()
×
934
{
935
    VCWidget* parent(closestParent());
×
936
    if (parent == NULL)
×
937
        return;
938

939
    VCFrame* frame = new VCFrame(parent, m_doc, true);
×
940
    setupWidget(frame, parent);
×
941
    m_doc->setModified();
×
942
}
943

944
void VirtualConsole::slotAddSoloFrame()
×
945
{
946
    VCWidget* parent(closestParent());
×
947
    if (parent == NULL)
×
948
        return;
949

950
    VCSoloFrame* soloframe = new VCSoloFrame(parent, m_doc, true);
×
951
    setupWidget(soloframe, parent);
×
952
    m_doc->setModified();
×
953
}
954

955
void VirtualConsole::slotAddLabel()
×
956
{
957
    VCWidget* parent(closestParent());
×
958
    if (parent == NULL)
×
959
        return;
960

961
    VCLabel* label = new VCLabel(parent, m_doc);
×
962
    setupWidget(label, parent);
×
963
    m_doc->setModified();
×
964
}
965

966
void VirtualConsole::slotAddAudioTriggers()
×
967
{
968
    VCWidget* parent(closestParent());
×
969
    if (parent == NULL)
×
970
        return;
971

972
    VCAudioTriggers* triggers = new VCAudioTriggers(parent, m_doc);
×
973
    setupWidget(triggers, parent);
×
974
    m_doc->setModified();
×
975
}
976

977
void VirtualConsole::slotAddClock()
×
978
{
979
    VCWidget* parent(closestParent());
×
980
    if (parent == NULL)
×
981
        return;
982

983
    VCClock* clock = new VCClock(parent, m_doc);
×
984
    setupWidget(clock, parent);
×
985
    m_doc->setModified();
×
986
}
987

988
void VirtualConsole::slotAddAnimation()
×
989
{
990
    VCWidget* parent(closestParent());
×
991
    if (parent == NULL)
×
992
        return;
993

994
    VCMatrix* matrix = new VCMatrix(parent, m_doc);
×
995
    setupWidget(matrix, parent);
×
996
    m_doc->setModified();
×
997
}
998

999
/*****************************************************************************
1000
 * Tools menu callbacks
1001
 *****************************************************************************/
1002

1003
void VirtualConsole::slotToolsSettings()
×
1004
{
1005
    VCPropertiesEditor vcpe(this, m_properties, m_doc->inputOutputMap());
×
1006
    if (vcpe.exec() == QDialog::Accepted)
×
1007
    {
1008
        m_properties = vcpe.properties();
×
1009
        contents()->resize(m_properties.size());
×
1010
        m_doc->inputOutputMap()->setGrandMasterChannelMode(m_properties.grandMasterChannelMode());
×
1011
        m_doc->inputOutputMap()->setGrandMasterValueMode(m_properties.grandMasterValueMode());
×
1012
        if (m_dockArea != NULL)
×
1013
            m_dockArea->setGrandMasterInvertedAppearance(m_properties.grandMasterSlideMode());
×
1014

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

1028
        m_doc->setModified();
×
1029
    }
×
1030
}
×
1031

1032
void VirtualConsole::slotWizard()
×
1033
{
1034
    FunctionWizard fw(this, m_doc);
×
1035
    if (fw.exec() == QDialog::Accepted){
×
1036
        m_doc->setModified();
×
1037
    }
1038
}
×
1039

1040
/*****************************************************************************
1041
 * Edit menu callbacks
1042
 *****************************************************************************/
1043

1044
void VirtualConsole::slotEditCut()
×
1045
{
1046
    /* No need to delete widgets in clipboard because they are actually just
1047
       MOVED to another parent during Paste when m_editAction == EditCut.
1048
       Cutting the widgets does nothing to them unless Paste is invoked. */
1049

1050
    /* Make the edit action valid only if there's something to cut */
1051
    if (m_selectedWidgets.size() == 0)
×
1052
    {
1053
        m_editAction = EditNone;
×
1054
        m_clipboard.clear();
×
1055
        m_editPasteAction->setEnabled(false);
×
1056
    }
1057
    else
1058
    {
1059
        m_editAction = EditCut;
×
1060
        m_clipboard = m_selectedWidgets;
×
1061
        m_editPasteAction->setEnabled(true);
×
1062
    }
1063

1064
    updateActions();
×
1065
}
×
1066

1067
void VirtualConsole::slotEditCopy()
×
1068
{
1069
    /* Make the edit action valid only if there's something to copy */
1070
    if (m_selectedWidgets.size() == 0)
×
1071
    {
1072
        m_editAction = EditNone;
×
1073
        m_clipboard.clear();
×
1074
        m_editPasteAction->setEnabled(false);
×
1075
    }
1076
    else
1077
    {
1078
        m_editAction = EditCopy;
×
1079
        m_clipboard = m_selectedWidgets;
×
1080
        m_editPasteAction->setEnabled(true);
×
1081
    }
1082
}
×
1083

1084
void VirtualConsole::slotEditPaste()
×
1085
{
1086
    if (m_clipboard.size() == 0)
×
1087
    {
1088
        /* Invalidate the edit action if there's nothing to paste */
1089
        m_editAction = EditNone;
×
1090
        m_editPasteAction->setEnabled(false);
×
1091
        return;
×
1092
    }
1093

1094
    VCWidget* parent;
1095
    VCWidget* widget;
1096
    QRect bounds;
×
1097

1098
    Q_ASSERT(contents() != NULL);
1099

1100
    /* Select the parent that gets the cut clipboard contents */
1101
    parent = closestParent();
×
1102

1103
    /* Get the bounding rect for all selected widgets */
1104
    QListIterator <VCWidget*> it(m_clipboard);
×
1105
    while (it.hasNext() == true)
×
1106
    {
1107
        widget = it.next();
×
1108
        Q_ASSERT(widget != NULL);
1109
        bounds = bounds.united(widget->geometry());
×
1110
    }
1111

1112
    /* Get the upcoming parent's last mouse click point */
1113
    QPoint cp(parent->lastClickPoint());
×
1114

1115
    if (m_editAction == EditCut)
×
1116
    {
1117
        it.toFront();
1118
        while (it.hasNext() == true)
×
1119
        {
1120
            widget = it.next();
×
1121
            Q_ASSERT(widget != NULL);
1122
            if (widget == parent)
×
1123
                continue;
×
1124

1125
            VCWidget* prevParent = qobject_cast<VCWidget*> (widget->parentWidget());
1126
            if (prevParent != NULL)
×
1127
                disconnectWidgetFromParent(widget, prevParent);
×
1128

1129
            /* Get widget's relative pos to the bounding rect */
1130
            QPoint p(widget->x() - bounds.x() + cp.x(),
×
1131
                     widget->y() - bounds.y() + cp.y());
×
1132

1133
            /* Reparent and move to the correct place */
1134
            widget->setParent(parent);
×
1135
            connectWidgetToParent(widget, parent);
×
1136
            widget->move(p);
×
1137
            widget->show();
×
1138
        }
1139

1140
        /* Clear clipboard after pasting stuff that was CUT */
1141
        m_clipboard.clear();
×
1142
        m_editPasteAction->setEnabled(false);
×
1143
    }
1144
    else if (m_editAction == EditCopy)
×
1145
    {
1146
        it.toFront();
1147
        while (it.hasNext() == true)
×
1148
        {
1149
            widget = it.next();
×
1150
            Q_ASSERT(widget != NULL);
1151
            if (widget == parent)
×
1152
                continue;
×
1153

1154
            /* Get widget's relative pos to the bounding rect */
1155
            QPoint p(widget->x() - bounds.x() + cp.x(),
×
1156
                     widget->y() - bounds.y() + cp.y());
×
1157

1158
            /* Create a copy and move to correct place */
1159
            VCWidget* copy = widget->createCopy(parent);
×
1160
            Q_ASSERT(copy != NULL);
1161
            addWidgetInMap(copy);
×
1162
            connectWidgetToParent(copy, parent);
×
1163
            copy->move(p);
×
1164
            copy->show();
×
1165
        }
1166
    }
1167

1168
    updateActions();
×
1169
}
1170

1171
void VirtualConsole::slotEditDelete()
×
1172
{
1173
    QString msg(tr("Do you wish to delete the selected widgets?"));
1174
    QString title(tr("Delete widgets"));
1175
    int result = QMessageBox::question(this, title, msg,
×
1176
                                       QMessageBox::Yes,
1177
                                       QMessageBox::No);
1178
    if (result == QMessageBox::Yes)
×
1179
    {
1180
        while (m_selectedWidgets.isEmpty() == false)
×
1181
        {
1182
            /* Consume the selected list until it is empty and
1183
               delete each widget. */
1184
            VCWidget* widget = m_selectedWidgets.takeFirst();
×
1185
            m_widgetsMap.remove(widget->id());
×
1186
            foreach (VCWidget* child, getChildren(widget))
×
1187
                m_widgetsMap.remove(child->id());
×
1188
            VCWidget* parent = qobject_cast<VCWidget*> (widget->parentWidget());
1189
            widget->deleteLater();
×
1190

1191
            if (parent != NULL)
×
1192
                disconnectWidgetFromParent(widget, parent);
×
1193

1194
            /* Remove the widget from clipboard as well so that
1195
               deleted widgets won't be pasted anymore anywhere */
1196
            m_clipboard.removeAll(widget);
×
1197
            m_editPasteAction->setEnabled(false);
×
1198
        }
1199

1200
        updateActions();
×
1201
    }
1202
    m_doc->setModified();
×
1203
}
×
1204

1205
void VirtualConsole::slotEditProperties()
×
1206
{
1207
    VCWidget* widget;
1208

1209
    Q_ASSERT(contents() != NULL);
1210

1211
    if (m_selectedWidgets.isEmpty() == true)
×
1212
        widget = contents();
×
1213
    else
1214
        widget = m_selectedWidgets.last();
×
1215

1216
    if (widget != NULL)
×
1217
        widget->editProperties();
×
1218
}
×
1219

1220
void VirtualConsole::slotEditRename()
×
1221
{
1222
    if (m_selectedWidgets.isEmpty() == true)
×
1223
        return;
×
1224

1225
    bool ok = false;
×
1226
    QString text(m_selectedWidgets.last()->caption());
×
1227
    text = QInputDialog::getText(this, tr("Rename widgets"), tr("Caption:"),
×
1228
                                 QLineEdit::Normal, text, &ok);
1229
    if (ok == true)
×
1230
    {
1231
        VCWidget* widget;
1232
        foreach (widget, m_selectedWidgets)
×
1233
            widget->setCaption(text);
×
1234
    }
1235
}
×
1236

1237
/*****************************************************************************
1238
 * Background menu callbacks
1239
 *****************************************************************************/
1240

1241
void VirtualConsole::slotBackgroundColor()
×
1242
{
1243
    QColor color;
×
1244

1245
    Q_ASSERT(contents() != NULL);
1246

1247
    if (m_selectedWidgets.isEmpty() == true)
×
1248
        color = contents()->backgroundColor();
×
1249
    else
1250
        color = m_selectedWidgets.last()->backgroundColor();
×
1251

1252
    color = QColorDialog::getColor(color);
×
1253
    if (color.isValid() == true)
×
1254
    {
1255
        if (m_selectedWidgets.isEmpty() == true)
×
1256
        {
1257
            contents()->setBackgroundColor(color);
×
1258
        }
1259
        else
1260
        {
1261
            VCWidget* widget;
1262
            foreach (widget, m_selectedWidgets)
×
1263
                widget->setBackgroundColor(color);
×
1264
        }
1265
    }
1266
}
×
1267

1268
void VirtualConsole::slotBackgroundImage()
×
1269
{
1270
    QString path;
1271

1272
    Q_ASSERT(contents() != NULL);
1273

1274
    if (m_selectedWidgets.isEmpty() == true)
×
1275
        path = contents()->backgroundImage();
×
1276
    else
1277
        path = m_selectedWidgets.last()->backgroundImage();
×
1278

1279
    path = QFileDialog::getOpenFileName(this,
×
1280
                                        tr("Select background image"),
×
1281
                                        path,
1282
                                        QString("%1 (*.png *.bmp *.jpg *.jpeg *.gif)").arg(tr("Images")));
×
1283
    if (path.isEmpty() == false)
×
1284
    {
1285
        if (m_selectedWidgets.isEmpty() == true)
×
1286
        {
1287
            contents()->setBackgroundImage(path);
×
1288
        }
1289
        else
1290
        {
1291
            VCWidget* widget;
1292
            foreach (widget, m_selectedWidgets)
×
1293
                widget->setBackgroundImage(path);
×
1294
        }
1295
    }
1296
}
×
1297

1298
void VirtualConsole::slotBackgroundNone()
×
1299
{
1300
    Q_ASSERT(contents() != NULL);
1301

1302
    if (m_selectedWidgets.isEmpty() == true)
×
1303
    {
1304
        contents()->resetBackgroundColor();
×
1305
    }
1306
    else
1307
    {
1308
        VCWidget* widget;
1309
        foreach (widget, m_selectedWidgets)
×
1310
            widget->resetBackgroundColor();
×
1311
    }
1312
}
×
1313

1314
/*****************************************************************************
1315
 * Foreground menu callbacks
1316
 *****************************************************************************/
1317

1318
void VirtualConsole::slotForegroundColor()
×
1319
{
1320
    Q_ASSERT(contents() != NULL);
1321

1322
    if (m_selectedWidgets.isEmpty() == true)
×
1323
        return;
×
1324

1325
    QColor color(m_selectedWidgets.last()->foregroundColor());
×
1326
    color = QColorDialog::getColor(color);
×
1327
    if (color.isValid() == true)
×
1328
    {
1329
        VCWidget* widget;
1330
        foreach (widget, m_selectedWidgets)
×
1331
            widget->setForegroundColor(color);
×
1332
    }
1333
}
1334

1335
void VirtualConsole::slotForegroundNone()
×
1336
{
1337
    Q_ASSERT(contents() != NULL);
1338

1339
    if (m_selectedWidgets.isEmpty() == true)
×
1340
        return;
1341

1342
    VCWidget* widget;
1343
    foreach (widget, m_selectedWidgets)
×
1344
        widget->resetForegroundColor();
×
1345
}
1346

1347
/*****************************************************************************
1348
 * Font menu callbacks
1349
 *****************************************************************************/
1350

1351
void VirtualConsole::slotFont()
×
1352
{
1353
    bool ok = false;
×
1354
    QFont font;
×
1355

1356
    Q_ASSERT(contents() != NULL);
1357

1358
    if (m_selectedWidgets.isEmpty() == true)
×
1359
        font = contents()->font();
×
1360
    else
1361
        font = m_selectedWidgets.last()->font();
×
1362

1363
    /* This crashes with Qt 4.6.x on OSX. Upgrade to 4.7.x. */
1364
    font = QFontDialog::getFont(&ok, font);
×
1365
    if (ok == true)
×
1366
    {
1367
        if (m_selectedWidgets.isEmpty() == true)
×
1368
        {
1369
            contents()->setFont(font);
×
1370
        }
1371
        else
1372
        {
1373
            VCWidget* widget;
1374
            foreach (widget, m_selectedWidgets)
×
1375
                widget->setFont(font);
×
1376
        }
1377
    }
1378
}
×
1379

1380
void VirtualConsole::slotResetFont()
×
1381
{
1382
    Q_ASSERT(contents() != NULL);
1383

1384
    if (m_selectedWidgets.isEmpty() == true)
×
1385
    {
1386
        contents()->resetFont();
×
1387
    }
1388
    else
1389
    {
1390
        VCWidget* widget;
1391
        foreach (widget, m_selectedWidgets)
×
1392
            widget->resetFont();
×
1393
    }
1394
}
×
1395

1396
/*****************************************************************************
1397
 * Stacking menu callbacks
1398
 *****************************************************************************/
1399

1400
void VirtualConsole::slotStackingRaise()
×
1401
{
1402
    Q_ASSERT(contents() != NULL);
1403

1404
    if (m_selectedWidgets.isEmpty() == true)
×
1405
        return;
1406

1407
    VCWidget* widget;
1408
    foreach (widget, m_selectedWidgets)
×
1409
        widget->raise();
×
1410

1411
    m_doc->setModified();
×
1412
}
1413

1414
void VirtualConsole::slotStackingLower()
×
1415
{
1416
    Q_ASSERT(contents() != NULL);
1417

1418
    if (m_selectedWidgets.isEmpty() == true)
×
1419
        return;
1420

1421
    VCWidget* widget;
1422
    foreach (widget, m_selectedWidgets)
×
1423
        widget->lower();
×
1424

1425
    m_doc->setModified();
×
1426
}
1427

1428
/*****************************************************************************
1429
 * Frame menu callbacks
1430
 *****************************************************************************/
1431

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

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

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

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

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

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

1456
void VirtualConsole::slotFrameNone()
×
1457
{
1458
    Q_ASSERT(contents() != NULL);
1459

1460
    if (m_selectedWidgets.isEmpty() == true)
×
1461
        return;
1462

1463
    VCWidget* widget;
1464
    foreach (widget, m_selectedWidgets)
×
1465
        widget->setFrameStyle(KVCFrameStyleNone);
×
1466
}
1467

1468
/*****************************************************************************
1469
 * Dock area
1470
 *****************************************************************************/
1471

1472
VCDockArea* VirtualConsole::dockArea() const
×
1473
{
1474
    return m_dockArea;
×
1475
}
1476

1477
void VirtualConsole::initDockArea()
76✔
1478
{
1479
    if (m_dockArea != NULL)
76✔
1480
        delete m_dockArea;
×
1481

1482
    m_dockArea = new VCDockArea(this, m_doc->inputOutputMap());
76✔
1483
    m_dockArea->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding);
76✔
1484

1485
    // Add the dock area into the master horizontal layout
1486
    layout()->addWidget(m_dockArea);
76✔
1487

1488
    /* Show the dock area by default */
1489
    m_dockArea->show();
76✔
1490
}
76✔
1491

1492
/*****************************************************************************
1493
 * Contents
1494
 *****************************************************************************/
1495

1496
VCFrame* VirtualConsole::contents() const
781✔
1497
{
1498
    return m_contents;
781✔
1499
}
1500

1501
void VirtualConsole::resetContents()
76✔
1502
{
1503
    if (m_contents != NULL)
76✔
1504
        delete m_contents;
×
1505

1506
    Q_ASSERT(m_scrollArea != NULL);
1507
    m_contents = new VCFrame(m_scrollArea, m_doc);
76✔
1508
    m_contents->setFrameStyle(0);
76✔
1509

1510
    // Get virtual console size from properties
1511
    QSize size(m_properties.size());
76✔
1512
    contents()->resize(size);
76✔
1513
    contents()->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
76✔
1514
    m_scrollArea->setWidget(contents());
76✔
1515

1516
    /* Disconnect old key handlers to prevent duplicates */
1517
    disconnect(this, SIGNAL(keyPressed(const QKeySequence&)),
76✔
1518
               contents(), SLOT(slotKeyPressed(const QKeySequence&)));
76✔
1519
    disconnect(this, SIGNAL(keyReleased(const QKeySequence&)),
76✔
1520
               contents(), SLOT(slotKeyReleased(const QKeySequence&)));
76✔
1521

1522
    /* Connect new key handlers */
1523
    connect(this, SIGNAL(keyPressed(const QKeySequence&)),
76✔
1524
            contents(), SLOT(slotKeyPressed(const QKeySequence&)));
76✔
1525
    connect(this, SIGNAL(keyReleased(const QKeySequence&)),
76✔
1526
            contents(), SLOT(slotKeyReleased(const QKeySequence&)));
76✔
1527

1528
    /* Make the contents area take up all available space */
1529
    contents()->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
76✔
1530

1531
    m_clipboard.clear();
76✔
1532
    m_selectedWidgets.clear();
76✔
1533
    m_latestWidgetId = 0;
76✔
1534
    m_widgetsMap.clear();
76✔
1535

1536
    /* Update actions' enabled status */
1537
    updateActions();
76✔
1538

1539
    /* Reset all properties but size */
1540
    m_properties.setGrandMasterChannelMode(GrandMaster::Intensity);
76✔
1541
    m_properties.setGrandMasterValueMode(GrandMaster::Reduce);
76✔
1542
    m_properties.setGrandMasterInputSource(InputOutputMap::invalidUniverse(), QLCChannel::invalid());
76✔
1543
}
76✔
1544

1545
void VirtualConsole::addWidgetInMap(VCWidget* widget)
1✔
1546
{
1547
    // Valid ID ?
1548
    if (widget->id() != VCWidget::invalidId())
1✔
1549
    {
1550
        // Maybe we don't know this widget yet
1551
        if (!m_widgetsMap.contains(widget->id()))
×
1552
        {
1553
            m_widgetsMap.insert(widget->id(), widget);
×
1554
            return;
×
1555
        }
1556

1557
        // Maybe we already know this widget
1558
        if (m_widgetsMap[widget->id()] == widget)
×
1559
        {
1560
            qDebug() << Q_FUNC_INFO << "widget" << widget->id() << "already in map";
1561
            return;
1562
        }
1563

1564
        // This widget id conflicts with another one we have to change it.
1565
        qDebug() << Q_FUNC_INFO << "widget id" << widget->id() << "conflicts, creating a new ID";
1566
    }
1567

1568
    quint32 wid = newWidgetId();
1✔
1569
    Q_ASSERT(!m_widgetsMap.contains(wid));
1570
    qDebug() << Q_FUNC_INFO << "id=" << wid;
1571
    widget->setID(wid);
1✔
1572
    m_widgetsMap.insert(wid, widget);
1✔
1573
}
1574

1575
void VirtualConsole::setupWidget(VCWidget *widget, VCWidget *parent)
×
1576
{
1577
    Q_ASSERT(widget != NULL);
1578
    Q_ASSERT(parent != NULL);
1579

1580
    addWidgetInMap(widget);
×
1581
    connectWidgetToParent(widget, parent);
×
1582
    widget->show();
×
1583
    widget->move(parent->lastClickPoint());
×
1584
    clearWidgetSelection();
×
1585
    setWidgetSelected(widget, true);
×
1586
}
×
1587

1588
VCWidget *VirtualConsole::widget(quint32 id)
×
1589
{
1590
    if (id == VCWidget::invalidId())
×
1591
        return NULL;
1592

1593
    return m_widgetsMap.value(id, NULL);
×
1594
}
1595

1596
void VirtualConsole::initContents()
76✔
1597
{
1598
    Q_ASSERT(layout() != NULL);
1599

1600
    m_scrollArea = new QScrollArea(this);
76✔
1601
    m_contentsLayout->addWidget(m_scrollArea);
76✔
1602
    m_scrollArea->setAlignment(Qt::AlignCenter);
76✔
1603
    m_scrollArea->setWidgetResizable(false);
76✔
1604

1605
    resetContents();
76✔
1606
}
76✔
1607

1608
/*****************************************************************************
1609
 * Key press handler
1610
 *****************************************************************************/
1611

1612
void VirtualConsole::keyPressEvent(QKeyEvent* event)
×
1613
{
1614
    if (event->isAutoRepeat() == true || event->key() == 0)
×
1615
    {
1616
        event->ignore();
1617
        return;
×
1618
    }
1619

1620
    QKeySequence seq(event->key() | (event->modifiers() & ~Qt::ControlModifier));
×
1621
    emit keyPressed(seq);
×
1622

1623
    event->accept();
1624
}
×
1625

1626
void VirtualConsole::keyReleaseEvent(QKeyEvent* event)
×
1627
{
1628
    if (event->isAutoRepeat() == true || event->key() == 0)
×
1629
    {
1630
        event->ignore();
1631
        return;
×
1632
    }
1633

1634
    QKeySequence seq(event->key() | event->modifiers());
×
1635
    emit keyReleased(seq);
×
1636

1637
    event->accept();
1638
}
×
1639

1640
/*****************************************************************************
1641
 * Main application mode
1642
 *****************************************************************************/
1643

1644
void VirtualConsole::toggleLiveEdit()
×
1645
{
1646
    // No live edit in Design Mode
1647
    Q_ASSERT(m_doc->mode() == Doc::Operate);
1648

1649
    if (m_liveEdit)
×
1650
    { // live edit was on, disable live edit
1651
        m_liveEdit = false;
×
1652
        disableEdit();
×
1653
    }
1654
    else
1655
    { // live edit was off, enable live edit
1656
        m_liveEdit = true;
×
1657
        enableEdit();
×
1658
    }
1659

1660
    // inform the widgets of the live edit status
1661
    QHash<quint32, VCWidget*>::iterator widgetIt = m_widgetsMap.begin();
×
1662
    while (widgetIt != m_widgetsMap.end())
×
1663
    {
1664
        VCWidget* widget = widgetIt.value();
×
1665
        widget->setLiveEdit(m_liveEdit);
×
1666
        ++widgetIt;
1667
    }
1668
    m_contents->setLiveEdit(m_liveEdit);
×
1669
}
×
1670

1671
bool VirtualConsole::liveEdit() const
177✔
1672
{
1673
    return m_liveEdit;
177✔
1674
}
1675

1676
void VirtualConsole::enableEdit()
80✔
1677
{
1678
    // Allow editing and adding in design mode
1679
    m_toolsSettingsAction->setEnabled(true);
80✔
1680
    m_editActionGroup->setEnabled(true);
80✔
1681
    m_addActionGroup->setEnabled(true);
80✔
1682
    m_bgActionGroup->setEnabled(true);
80✔
1683
    m_fgActionGroup->setEnabled(true);
80✔
1684
    m_fontActionGroup->setEnabled(true);
80✔
1685
    m_frameActionGroup->setEnabled(true);
80✔
1686
    m_stackingActionGroup->setEnabled(true);
80✔
1687
    m_functionWizardAction->setEnabled(true);
80✔
1688

1689
    // Set action shortcuts for design mode
1690
    m_addButtonAction->setShortcut(QKeySequence("CTRL+SHIFT+B"));
80✔
1691
    m_addButtonMatrixAction->setShortcut(QKeySequence("CTRL+SHIFT+M"));
80✔
1692
    m_addSliderAction->setShortcut(QKeySequence("CTRL+SHIFT+S"));
80✔
1693
    m_addSliderMatrixAction->setShortcut(QKeySequence("CTRL+SHIFT+I"));
80✔
1694
    m_addKnobAction->setShortcut(QKeySequence("CTRL+SHIFT+K"));
80✔
1695
    m_addSpeedDialAction->setShortcut(QKeySequence("CTRL+SHIFT+D"));
80✔
1696
    m_addXYPadAction->setShortcut(QKeySequence("CTRL+SHIFT+X"));
80✔
1697
    m_addCueListAction->setShortcut(QKeySequence("CTRL+SHIFT+C"));
80✔
1698
    m_addFrameAction->setShortcut(QKeySequence("CTRL+SHIFT+F"));
80✔
1699
    m_addSoloFrameAction->setShortcut(QKeySequence("CTRL+SHIFT+O"));
80✔
1700
    m_addLabelAction->setShortcut(QKeySequence("CTRL+SHIFT+L"));
80✔
1701
    m_addAudioTriggersAction->setShortcut(QKeySequence("CTRL+SHIFT+A"));
80✔
1702
    m_addClockAction->setShortcut(QKeySequence("CTRL+SHIFT+T"));
80✔
1703
    m_addAnimationAction->setShortcut(QKeySequence("CTRL+SHIFT+R"));
80✔
1704

1705
    m_editCutAction->setShortcut(QKeySequence("CTRL+X"));
80✔
1706
    m_editCopyAction->setShortcut(QKeySequence("CTRL+C"));
80✔
1707
    m_editPasteAction->setShortcut(QKeySequence("CTRL+V"));
80✔
1708
    m_editDeleteAction->setShortcut(QKeySequence("Delete"));
80✔
1709
    m_editPropertiesAction->setShortcut(QKeySequence("CTRL+E"));
80✔
1710

1711
    m_bgColorAction->setShortcut(QKeySequence("SHIFT+B"));
80✔
1712
    m_bgImageAction->setShortcut(QKeySequence("SHIFT+I"));
80✔
1713
    m_bgDefaultAction->setShortcut(QKeySequence("SHIFT+ALT+B"));
80✔
1714
    m_fgColorAction->setShortcut(QKeySequence("SHIFT+F"));
80✔
1715
    m_fgDefaultAction->setShortcut(QKeySequence("SHIFT+ALT+F"));
80✔
1716
    m_fontAction->setShortcut(QKeySequence("SHIFT+O"));
80✔
1717
    m_resetFontAction->setShortcut(QKeySequence("SHIFT+ALT+O"));
80✔
1718
    m_frameSunkenAction->setShortcut(QKeySequence("SHIFT+S"));
80✔
1719
    m_frameRaisedAction->setShortcut(QKeySequence("SHIFT+R"));
80✔
1720
    m_frameNoneAction->setShortcut(QKeySequence("SHIFT+ALT+S"));
80✔
1721

1722
    m_stackingRaiseAction->setShortcut(QKeySequence("SHIFT+UP"));
80✔
1723
    m_stackingLowerAction->setShortcut(QKeySequence("SHIFT+DOWN"));
80✔
1724

1725
    // Show toolbar
1726
    m_toolbar->show();
80✔
1727
}
80✔
1728

1729
void VirtualConsole::disableEdit()
15✔
1730
{
1731
    // Don't allow editing or adding in operate mode
1732
    m_toolsSettingsAction->setEnabled(false);
15✔
1733
    m_editActionGroup->setEnabled(false);
15✔
1734
    m_addActionGroup->setEnabled(false);
15✔
1735
    m_bgActionGroup->setEnabled(false);
15✔
1736
    m_fgActionGroup->setEnabled(false);
15✔
1737
    m_fontActionGroup->setEnabled(false);
15✔
1738
    m_frameActionGroup->setEnabled(false);
15✔
1739
    m_stackingActionGroup->setEnabled(false);
15✔
1740
    m_functionWizardAction->setEnabled(false);
15✔
1741

1742
    // Disable action shortcuts in operate mode
1743
    m_addButtonAction->setShortcut(QKeySequence());
15✔
1744
    m_addButtonMatrixAction->setShortcut(QKeySequence());
15✔
1745
    m_addSliderAction->setShortcut(QKeySequence());
15✔
1746
    m_addSliderMatrixAction->setShortcut(QKeySequence());
15✔
1747
    m_addKnobAction->setShortcut(QKeySequence());
15✔
1748
    m_addSpeedDialAction->setShortcut(QKeySequence());
15✔
1749
    m_addXYPadAction->setShortcut(QKeySequence());
15✔
1750
    m_addCueListAction->setShortcut(QKeySequence());
15✔
1751
    m_addFrameAction->setShortcut(QKeySequence());
15✔
1752
    m_addSoloFrameAction->setShortcut(QKeySequence());
15✔
1753
    m_addLabelAction->setShortcut(QKeySequence());
15✔
1754
    m_addAudioTriggersAction->setShortcut(QKeySequence());
15✔
1755
    m_addClockAction->setShortcut(QKeySequence());
15✔
1756
    m_addAnimationAction->setShortcut(QKeySequence());
15✔
1757

1758
    m_editCutAction->setShortcut(QKeySequence());
15✔
1759
    m_editCopyAction->setShortcut(QKeySequence());
15✔
1760
    m_editPasteAction->setShortcut(QKeySequence());
15✔
1761
    m_editDeleteAction->setShortcut(QKeySequence());
15✔
1762
    m_editPropertiesAction->setShortcut(QKeySequence());
15✔
1763

1764
    m_bgColorAction->setShortcut(QKeySequence());
15✔
1765
    m_bgImageAction->setShortcut(QKeySequence());
15✔
1766
    m_bgDefaultAction->setShortcut(QKeySequence());
15✔
1767
    m_fgColorAction->setShortcut(QKeySequence());
15✔
1768
    m_fgDefaultAction->setShortcut(QKeySequence());
15✔
1769
    m_fontAction->setShortcut(QKeySequence());
15✔
1770
    m_resetFontAction->setShortcut(QKeySequence());
15✔
1771
    m_frameSunkenAction->setShortcut(QKeySequence());
15✔
1772
    m_frameRaisedAction->setShortcut(QKeySequence());
15✔
1773
    m_frameNoneAction->setShortcut(QKeySequence());
15✔
1774

1775
    m_stackingRaiseAction->setShortcut(QKeySequence());
15✔
1776
    m_stackingLowerAction->setShortcut(QKeySequence());
15✔
1777

1778
    // Hide toolbar; there's nothing usable there in operate mode
1779
    m_toolbar->hide();
15✔
1780

1781
    // Make sure the virtual console contents has the focus.
1782
    // Without this, key combinations don't work unless
1783
    // the user clicks on some VC area
1784
    m_contents->setFocus();
15✔
1785
}
15✔
1786

1787
void VirtualConsole::slotModeChanged(Doc::Mode mode)
95✔
1788
{
1789
    if (mode == Doc::Operate)
95✔
1790
    { // Switch from Design mode to Operate mode
1791
        // Hide edit tools
1792
        disableEdit();
15✔
1793
    }
1794
    else
1795
    { // Switch from Operate mode to Design mode
1796
        if (m_liveEdit)
80✔
1797
        {
1798
            // Edit tools already shown,
1799
            // inform the widgets that we are out of live edit mode
1800
            m_liveEdit = false;
×
1801
            QHash<quint32, VCWidget*>::iterator widgetIt = m_widgetsMap.begin();
×
1802
            while (widgetIt != m_widgetsMap.end())
×
1803
            {
1804
                VCWidget* widget = widgetIt.value();
×
1805
                widget->cancelLiveEdit();
×
1806
                ++widgetIt;
1807
            }
1808
            m_contents->cancelLiveEdit();
×
1809
        }
1810
        else
1811
        {
1812
            // Show edit tools
1813
            enableEdit();
80✔
1814
        }
1815
    }
1816
}
95✔
1817

1818
/*****************************************************************************
1819
 * Load & Save
1820
 *****************************************************************************/
1821

1822
bool VirtualConsole::loadXML(QXmlStreamReader &root)
×
1823
{
1824
    if (root.name() != KXMLQLCVirtualConsole)
×
1825
    {
1826
        qWarning() << Q_FUNC_INFO << "Virtual Console node not found";
×
1827
        return false;
×
1828
    }
1829

1830
    while (root.readNextStartElement())
×
1831
    {
1832
        //qDebug() << "VC tag:" << root.name();
1833
        if (root.name() == KXMLQLCVCProperties)
×
1834
        {
1835
            /* Properties */
1836
            m_properties.loadXML(root);
×
1837
            QSize size(m_properties.size());
×
1838
            contents()->resize(size);
×
1839
            contents()->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
×
1840
        }
1841
        else if (root.name() == KXMLQLCVCFrame)
×
1842
        {
1843
            /* Contents */
1844
            Q_ASSERT(m_contents != NULL);
1845
            m_contents->loadXML(root);
×
1846
        }
1847
        else
1848
        {
1849
            qWarning() << Q_FUNC_INFO << "Unknown Virtual Console tag"
×
1850
                       << root.name().toString();
×
1851
            root.skipCurrentElement();
×
1852
        }
1853
    }
1854

1855
    return true;
1856
}
1857

1858
bool VirtualConsole::saveXML(QXmlStreamWriter *doc)
×
1859
{
1860
    Q_ASSERT(doc != NULL);
1861

1862
    /* Virtual Console entry */
1863
    doc->writeStartElement(KXMLQLCVirtualConsole);
×
1864

1865
    /* Contents */
1866
    Q_ASSERT(m_contents != NULL);
1867
    m_contents->saveXML(doc);
×
1868

1869
    /* Properties */
1870
    m_properties.saveXML(doc);
×
1871

1872
    /* End the <VirtualConsole> tag */
1873
    doc->writeEndElement();
×
1874

1875
    return true;
×
1876
}
1877

1878
QList<VCWidget *> VirtualConsole::getChildren(VCWidget *obj)
×
1879
{
1880
    QList<VCWidget *> list;
1881
    if (obj == NULL)
×
1882
        return list;
1883
    QListIterator <VCWidget*> it(obj->findChildren<VCWidget*>());
×
1884
    while (it.hasNext() == true)
×
1885
    {
1886
        VCWidget* child = it.next();
×
1887
        list.append(child);
×
1888
        list.append(getChildren(child));
×
1889
    }
1890
    return list;
1891
}
×
1892

1893
void VirtualConsole::postLoad()
×
1894
{
1895
    m_contents->postLoad();
×
1896

1897
    /* apply GM values
1898
      this should probably be placed in another place, but at the moment m_properties
1899
      is just loaded in VirtualConsole */
1900
    m_doc->inputOutputMap()->setGrandMasterValue(255);
×
1901
    m_doc->inputOutputMap()->setGrandMasterValueMode(m_properties.grandMasterValueMode());
×
1902
    m_doc->inputOutputMap()->setGrandMasterChannelMode(m_properties.grandMasterChannelMode());
×
1903

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

1928
    m_contents->setFocus();
×
1929

1930
    emit loaded();
×
1931
}
×
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