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

mcallegari / qlcplus / 14499310713

16 Apr 2025 05:57PM UTC coverage: 31.873% (+0.02%) from 31.853%
14499310713

push

github

mcallegari
Restore VC properties default page and update changelog

14691 of 46092 relevant lines covered (31.87%)

26441.99 hits per line

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

50.45
/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()
974✔
173
{
174
    return s_instance;
974✔
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
306✔
200
{
201
    return m_properties;
306✔
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
        {
1014
            m_dockArea->setGrandMasterVisible(m_properties.grandMasterVisible());
×
1015
            m_dockArea->setGrandMasterInvertedAppearance(m_properties.grandMasterSliderMode());
×
1016
        }
1017

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

1031
        m_doc->setModified();
×
1032
    }
×
1033
}
×
1034

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

1043
/*****************************************************************************
1044
 * Edit menu callbacks
1045
 *****************************************************************************/
1046

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

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

1067
    updateActions();
×
1068
}
×
1069

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

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

1097
    VCWidget* parent;
1098
    VCWidget* widget;
1099
    QRect bounds;
×
1100

1101
    Q_ASSERT(contents() != NULL);
1102

1103
    /* Select the parent that gets the cut clipboard contents */
1104
    parent = closestParent();
×
1105

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

1115
    /* Get the upcoming parent's last mouse click point */
1116
    QPoint cp(parent->lastClickPoint());
×
1117

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

1128
            VCWidget* prevParent = qobject_cast<VCWidget*> (widget->parentWidget());
1129
            if (prevParent != NULL)
×
1130
                disconnectWidgetFromParent(widget, prevParent);
×
1131

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

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

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

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

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

1171
    updateActions();
×
1172
}
1173

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

1194
            if (parent != NULL)
×
1195
                disconnectWidgetFromParent(widget, parent);
×
1196

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

1203
        updateActions();
×
1204
    }
1205
    m_doc->setModified();
×
1206
}
×
1207

1208
void VirtualConsole::slotEditProperties()
×
1209
{
1210
    VCWidget* widget;
1211

1212
    Q_ASSERT(contents() != NULL);
1213

1214
    if (m_selectedWidgets.isEmpty() == true)
×
1215
        widget = contents();
×
1216
    else
1217
        widget = m_selectedWidgets.last();
×
1218

1219
    if (widget != NULL)
×
1220
        widget->editProperties();
×
1221
}
×
1222

1223
void VirtualConsole::slotEditRename()
×
1224
{
1225
    if (m_selectedWidgets.isEmpty() == true)
×
1226
        return;
×
1227

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

1240
/*****************************************************************************
1241
 * Background menu callbacks
1242
 *****************************************************************************/
1243

1244
void VirtualConsole::slotBackgroundColor()
×
1245
{
1246
    QColor color;
×
1247

1248
    Q_ASSERT(contents() != NULL);
1249

1250
    if (m_selectedWidgets.isEmpty() == true)
×
1251
        color = contents()->backgroundColor();
×
1252
    else
1253
        color = m_selectedWidgets.last()->backgroundColor();
×
1254

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

1271
void VirtualConsole::slotBackgroundImage()
×
1272
{
1273
    QString path;
1274

1275
    Q_ASSERT(contents() != NULL);
1276

1277
    if (m_selectedWidgets.isEmpty() == true)
×
1278
        path = contents()->backgroundImage();
×
1279
    else
1280
        path = m_selectedWidgets.last()->backgroundImage();
×
1281

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

1301
void VirtualConsole::slotBackgroundNone()
×
1302
{
1303
    Q_ASSERT(contents() != NULL);
1304

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

1317
/*****************************************************************************
1318
 * Foreground menu callbacks
1319
 *****************************************************************************/
1320

1321
void VirtualConsole::slotForegroundColor()
×
1322
{
1323
    Q_ASSERT(contents() != NULL);
1324

1325
    if (m_selectedWidgets.isEmpty() == true)
×
1326
        return;
×
1327

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

1338
void VirtualConsole::slotForegroundNone()
×
1339
{
1340
    Q_ASSERT(contents() != NULL);
1341

1342
    if (m_selectedWidgets.isEmpty() == true)
×
1343
        return;
1344

1345
    VCWidget* widget;
1346
    foreach (widget, m_selectedWidgets)
×
1347
        widget->resetForegroundColor();
×
1348
}
1349

1350
/*****************************************************************************
1351
 * Font menu callbacks
1352
 *****************************************************************************/
1353

1354
void VirtualConsole::slotFont()
×
1355
{
1356
    bool ok = false;
×
1357
    QFont font;
×
1358

1359
    Q_ASSERT(contents() != NULL);
1360

1361
    if (m_selectedWidgets.isEmpty() == true)
×
1362
        font = contents()->font();
×
1363
    else
1364
        font = m_selectedWidgets.last()->font();
×
1365

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

1383
void VirtualConsole::slotResetFont()
×
1384
{
1385
    Q_ASSERT(contents() != NULL);
1386

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

1399
/*****************************************************************************
1400
 * Stacking menu callbacks
1401
 *****************************************************************************/
1402

1403
void VirtualConsole::slotStackingRaise()
×
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->raise();
×
1413

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

1417
void VirtualConsole::slotStackingLower()
×
1418
{
1419
    Q_ASSERT(contents() != NULL);
1420

1421
    if (m_selectedWidgets.isEmpty() == true)
×
1422
        return;
1423

1424
    VCWidget* widget;
1425
    foreach (widget, m_selectedWidgets)
×
1426
        widget->lower();
×
1427

1428
    m_doc->setModified();
×
1429
}
1430

1431
/*****************************************************************************
1432
 * Frame menu callbacks
1433
 *****************************************************************************/
1434

1435
void VirtualConsole::slotFrameSunken()
×
1436
{
1437
    Q_ASSERT(contents() != NULL);
1438

1439
    if (m_selectedWidgets.isEmpty() == true)
×
1440
        return;
1441

1442
    VCWidget* widget;
1443
    foreach (widget, m_selectedWidgets)
×
1444
        widget->setFrameStyle(KVCFrameStyleSunken);
×
1445
}
1446

1447
void VirtualConsole::slotFrameRaised()
×
1448
{
1449
    Q_ASSERT(contents() != NULL);
1450

1451
    if (m_selectedWidgets.isEmpty() == true)
×
1452
        return;
1453

1454
    VCWidget* widget;
1455
    foreach (widget, m_selectedWidgets)
×
1456
        widget->setFrameStyle(KVCFrameStyleRaised);
×
1457
}
1458

1459
void VirtualConsole::slotFrameNone()
×
1460
{
1461
    Q_ASSERT(contents() != NULL);
1462

1463
    if (m_selectedWidgets.isEmpty() == true)
×
1464
        return;
1465

1466
    VCWidget* widget;
1467
    foreach (widget, m_selectedWidgets)
×
1468
        widget->setFrameStyle(KVCFrameStyleNone);
×
1469
}
1470

1471
/*****************************************************************************
1472
 * Dock area
1473
 *****************************************************************************/
1474

1475
VCDockArea* VirtualConsole::dockArea() const
×
1476
{
1477
    return m_dockArea;
×
1478
}
1479

1480
void VirtualConsole::initDockArea()
76✔
1481
{
1482
    if (m_dockArea != NULL)
76✔
1483
        delete m_dockArea;
×
1484

1485
    m_dockArea = new VCDockArea(this, m_doc->inputOutputMap());
76✔
1486
    m_dockArea->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Expanding);
76✔
1487

1488
    // Add the dock area into the master horizontal layout
1489
    layout()->addWidget(m_dockArea);
76✔
1490

1491
    /* Show the dock area by default */
1492
    m_dockArea->show();
76✔
1493
}
76✔
1494

1495
/*****************************************************************************
1496
 * Contents
1497
 *****************************************************************************/
1498

1499
VCFrame* VirtualConsole::contents() const
781✔
1500
{
1501
    return m_contents;
781✔
1502
}
1503

1504
void VirtualConsole::resetContents()
76✔
1505
{
1506
    if (m_contents != NULL)
76✔
1507
        delete m_contents;
×
1508

1509
    Q_ASSERT(m_scrollArea != NULL);
1510
    m_contents = new VCFrame(m_scrollArea, m_doc);
76✔
1511
    m_contents->setFrameStyle(0);
76✔
1512

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

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

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

1531
    /* Make the contents area take up all available space */
1532
    contents()->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
76✔
1533

1534
    m_clipboard.clear();
76✔
1535
    m_selectedWidgets.clear();
76✔
1536
    m_latestWidgetId = 0;
76✔
1537
    m_widgetsMap.clear();
76✔
1538

1539
    /* Update actions' enabled status */
1540
    updateActions();
76✔
1541

1542
    /* Reset all properties but size */
1543
    m_properties.setGrandMasterVisible(true);
76✔
1544
    m_properties.setGrandMasterSliderMode(GrandMaster::Normal);
76✔
1545
    m_properties.setGrandMasterChannelMode(GrandMaster::Intensity);
76✔
1546
    m_properties.setGrandMasterValueMode(GrandMaster::Reduce);
76✔
1547
    m_properties.setGrandMasterInputSource(InputOutputMap::invalidUniverse(), QLCChannel::invalid());
76✔
1548

1549
    m_dockArea->setGrandMasterVisible(m_properties.grandMasterVisible());
76✔
1550
    m_dockArea->setGrandMasterInvertedAppearance(m_properties.grandMasterSliderMode());
76✔
1551
}
76✔
1552

1553
void VirtualConsole::addWidgetInMap(VCWidget* widget)
1✔
1554
{
1555
    // Valid ID ?
1556
    if (widget->id() != VCWidget::invalidId())
1✔
1557
    {
1558
        // Maybe we don't know this widget yet
1559
        if (!m_widgetsMap.contains(widget->id()))
×
1560
        {
1561
            m_widgetsMap.insert(widget->id(), widget);
×
1562
            return;
×
1563
        }
1564

1565
        // Maybe we already know this widget
1566
        if (m_widgetsMap[widget->id()] == widget)
×
1567
        {
1568
            qDebug() << Q_FUNC_INFO << "widget" << widget->id() << "already in map";
1569
            return;
1570
        }
1571

1572
        // This widget id conflicts with another one we have to change it.
1573
        qDebug() << Q_FUNC_INFO << "widget id" << widget->id() << "conflicts, creating a new ID";
1574
    }
1575

1576
    quint32 wid = newWidgetId();
1✔
1577
    Q_ASSERT(!m_widgetsMap.contains(wid));
1578
    qDebug() << Q_FUNC_INFO << "id=" << wid;
1579
    widget->setID(wid);
1✔
1580
    m_widgetsMap.insert(wid, widget);
1✔
1581
}
1582

1583
void VirtualConsole::setupWidget(VCWidget *widget, VCWidget *parent)
×
1584
{
1585
    Q_ASSERT(widget != NULL);
1586
    Q_ASSERT(parent != NULL);
1587

1588
    addWidgetInMap(widget);
×
1589
    connectWidgetToParent(widget, parent);
×
1590
    widget->show();
×
1591
    widget->move(parent->lastClickPoint());
×
1592
    clearWidgetSelection();
×
1593
    setWidgetSelected(widget, true);
×
1594
}
×
1595

1596
VCWidget *VirtualConsole::widget(quint32 id)
×
1597
{
1598
    if (id == VCWidget::invalidId())
×
1599
        return NULL;
1600

1601
    return m_widgetsMap.value(id, NULL);
×
1602
}
1603

1604
void VirtualConsole::initContents()
76✔
1605
{
1606
    Q_ASSERT(layout() != NULL);
1607

1608
    m_scrollArea = new QScrollArea(this);
76✔
1609
    m_contentsLayout->addWidget(m_scrollArea);
76✔
1610
    m_scrollArea->setAlignment(Qt::AlignCenter);
76✔
1611
    m_scrollArea->setWidgetResizable(false);
76✔
1612

1613
    resetContents();
76✔
1614
}
76✔
1615

1616
/*****************************************************************************
1617
 * Key press handler
1618
 *****************************************************************************/
1619

1620
void VirtualConsole::keyPressEvent(QKeyEvent* event)
×
1621
{
1622
    if (event->isAutoRepeat() == true || event->key() == 0)
×
1623
    {
1624
        event->ignore();
1625
        return;
×
1626
    }
1627

1628
    QKeySequence seq(event->key() | (event->modifiers() & ~Qt::ControlModifier));
×
1629
    emit keyPressed(seq);
×
1630

1631
    event->accept();
1632
}
×
1633

1634
void VirtualConsole::keyReleaseEvent(QKeyEvent* event)
×
1635
{
1636
    if (event->isAutoRepeat() == true || event->key() == 0)
×
1637
    {
1638
        event->ignore();
1639
        return;
×
1640
    }
1641

1642
    QKeySequence seq(event->key() | event->modifiers());
×
1643
    emit keyReleased(seq);
×
1644

1645
    event->accept();
1646
}
×
1647

1648
/*****************************************************************************
1649
 * Main application mode
1650
 *****************************************************************************/
1651

1652
void VirtualConsole::toggleLiveEdit()
×
1653
{
1654
    // No live edit in Design Mode
1655
    Q_ASSERT(m_doc->mode() == Doc::Operate);
1656

1657
    if (m_liveEdit)
×
1658
    { // live edit was on, disable live edit
1659
        m_liveEdit = false;
×
1660
        disableEdit();
×
1661
    }
1662
    else
1663
    { // live edit was off, enable live edit
1664
        m_liveEdit = true;
×
1665
        enableEdit();
×
1666
    }
1667

1668
    // inform the widgets of the live edit status
1669
    QHash<quint32, VCWidget*>::iterator widgetIt = m_widgetsMap.begin();
×
1670
    while (widgetIt != m_widgetsMap.end())
×
1671
    {
1672
        VCWidget* widget = widgetIt.value();
×
1673
        widget->setLiveEdit(m_liveEdit);
×
1674
        ++widgetIt;
1675
    }
1676
    m_contents->setLiveEdit(m_liveEdit);
×
1677
}
×
1678

1679
bool VirtualConsole::liveEdit() const
177✔
1680
{
1681
    return m_liveEdit;
177✔
1682
}
1683

1684
void VirtualConsole::enableEdit()
80✔
1685
{
1686
    // Allow editing and adding in design mode
1687
    m_toolsSettingsAction->setEnabled(true);
80✔
1688
    m_editActionGroup->setEnabled(true);
80✔
1689
    m_addActionGroup->setEnabled(true);
80✔
1690
    m_bgActionGroup->setEnabled(true);
80✔
1691
    m_fgActionGroup->setEnabled(true);
80✔
1692
    m_fontActionGroup->setEnabled(true);
80✔
1693
    m_frameActionGroup->setEnabled(true);
80✔
1694
    m_stackingActionGroup->setEnabled(true);
80✔
1695
    m_functionWizardAction->setEnabled(true);
80✔
1696

1697
    // Set action shortcuts for design mode
1698
    m_addButtonAction->setShortcut(QKeySequence("CTRL+SHIFT+B"));
80✔
1699
    m_addButtonMatrixAction->setShortcut(QKeySequence("CTRL+SHIFT+M"));
80✔
1700
    m_addSliderAction->setShortcut(QKeySequence("CTRL+SHIFT+S"));
80✔
1701
    m_addSliderMatrixAction->setShortcut(QKeySequence("CTRL+SHIFT+I"));
80✔
1702
    m_addKnobAction->setShortcut(QKeySequence("CTRL+SHIFT+K"));
80✔
1703
    m_addSpeedDialAction->setShortcut(QKeySequence("CTRL+SHIFT+D"));
80✔
1704
    m_addXYPadAction->setShortcut(QKeySequence("CTRL+SHIFT+X"));
80✔
1705
    m_addCueListAction->setShortcut(QKeySequence("CTRL+SHIFT+C"));
80✔
1706
    m_addFrameAction->setShortcut(QKeySequence("CTRL+SHIFT+F"));
80✔
1707
    m_addSoloFrameAction->setShortcut(QKeySequence("CTRL+SHIFT+O"));
80✔
1708
    m_addLabelAction->setShortcut(QKeySequence("CTRL+SHIFT+L"));
80✔
1709
    m_addAudioTriggersAction->setShortcut(QKeySequence("CTRL+SHIFT+A"));
80✔
1710
    m_addClockAction->setShortcut(QKeySequence("CTRL+SHIFT+T"));
80✔
1711
    m_addAnimationAction->setShortcut(QKeySequence("CTRL+SHIFT+R"));
80✔
1712

1713
    m_editCutAction->setShortcut(QKeySequence("CTRL+X"));
80✔
1714
    m_editCopyAction->setShortcut(QKeySequence("CTRL+C"));
80✔
1715
    m_editPasteAction->setShortcut(QKeySequence("CTRL+V"));
80✔
1716
    m_editDeleteAction->setShortcut(QKeySequence("Delete"));
80✔
1717
    m_editPropertiesAction->setShortcut(QKeySequence("CTRL+E"));
80✔
1718

1719
    m_bgColorAction->setShortcut(QKeySequence("SHIFT+B"));
80✔
1720
    m_bgImageAction->setShortcut(QKeySequence("SHIFT+I"));
80✔
1721
    m_bgDefaultAction->setShortcut(QKeySequence("SHIFT+ALT+B"));
80✔
1722
    m_fgColorAction->setShortcut(QKeySequence("SHIFT+F"));
80✔
1723
    m_fgDefaultAction->setShortcut(QKeySequence("SHIFT+ALT+F"));
80✔
1724
    m_fontAction->setShortcut(QKeySequence("SHIFT+O"));
80✔
1725
    m_resetFontAction->setShortcut(QKeySequence("SHIFT+ALT+O"));
80✔
1726
    m_frameSunkenAction->setShortcut(QKeySequence("SHIFT+S"));
80✔
1727
    m_frameRaisedAction->setShortcut(QKeySequence("SHIFT+R"));
80✔
1728
    m_frameNoneAction->setShortcut(QKeySequence("SHIFT+ALT+S"));
80✔
1729

1730
    m_stackingRaiseAction->setShortcut(QKeySequence("SHIFT+UP"));
80✔
1731
    m_stackingLowerAction->setShortcut(QKeySequence("SHIFT+DOWN"));
80✔
1732

1733
    // Show toolbar
1734
    m_toolbar->show();
80✔
1735
}
80✔
1736

1737
void VirtualConsole::disableEdit()
15✔
1738
{
1739
    // Don't allow editing or adding in operate mode
1740
    m_toolsSettingsAction->setEnabled(false);
15✔
1741
    m_editActionGroup->setEnabled(false);
15✔
1742
    m_addActionGroup->setEnabled(false);
15✔
1743
    m_bgActionGroup->setEnabled(false);
15✔
1744
    m_fgActionGroup->setEnabled(false);
15✔
1745
    m_fontActionGroup->setEnabled(false);
15✔
1746
    m_frameActionGroup->setEnabled(false);
15✔
1747
    m_stackingActionGroup->setEnabled(false);
15✔
1748
    m_functionWizardAction->setEnabled(false);
15✔
1749

1750
    // Disable action shortcuts in operate mode
1751
    m_addButtonAction->setShortcut(QKeySequence());
15✔
1752
    m_addButtonMatrixAction->setShortcut(QKeySequence());
15✔
1753
    m_addSliderAction->setShortcut(QKeySequence());
15✔
1754
    m_addSliderMatrixAction->setShortcut(QKeySequence());
15✔
1755
    m_addKnobAction->setShortcut(QKeySequence());
15✔
1756
    m_addSpeedDialAction->setShortcut(QKeySequence());
15✔
1757
    m_addXYPadAction->setShortcut(QKeySequence());
15✔
1758
    m_addCueListAction->setShortcut(QKeySequence());
15✔
1759
    m_addFrameAction->setShortcut(QKeySequence());
15✔
1760
    m_addSoloFrameAction->setShortcut(QKeySequence());
15✔
1761
    m_addLabelAction->setShortcut(QKeySequence());
15✔
1762
    m_addAudioTriggersAction->setShortcut(QKeySequence());
15✔
1763
    m_addClockAction->setShortcut(QKeySequence());
15✔
1764
    m_addAnimationAction->setShortcut(QKeySequence());
15✔
1765

1766
    m_editCutAction->setShortcut(QKeySequence());
15✔
1767
    m_editCopyAction->setShortcut(QKeySequence());
15✔
1768
    m_editPasteAction->setShortcut(QKeySequence());
15✔
1769
    m_editDeleteAction->setShortcut(QKeySequence());
15✔
1770
    m_editPropertiesAction->setShortcut(QKeySequence());
15✔
1771

1772
    m_bgColorAction->setShortcut(QKeySequence());
15✔
1773
    m_bgImageAction->setShortcut(QKeySequence());
15✔
1774
    m_bgDefaultAction->setShortcut(QKeySequence());
15✔
1775
    m_fgColorAction->setShortcut(QKeySequence());
15✔
1776
    m_fgDefaultAction->setShortcut(QKeySequence());
15✔
1777
    m_fontAction->setShortcut(QKeySequence());
15✔
1778
    m_resetFontAction->setShortcut(QKeySequence());
15✔
1779
    m_frameSunkenAction->setShortcut(QKeySequence());
15✔
1780
    m_frameRaisedAction->setShortcut(QKeySequence());
15✔
1781
    m_frameNoneAction->setShortcut(QKeySequence());
15✔
1782

1783
    m_stackingRaiseAction->setShortcut(QKeySequence());
15✔
1784
    m_stackingLowerAction->setShortcut(QKeySequence());
15✔
1785

1786
    // Hide toolbar; there's nothing usable there in operate mode
1787
    m_toolbar->hide();
15✔
1788

1789
    // Make sure the virtual console contents has the focus.
1790
    // Without this, key combinations don't work unless
1791
    // the user clicks on some VC area
1792
    m_contents->setFocus();
15✔
1793
}
15✔
1794

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

1826
/*****************************************************************************
1827
 * Load & Save
1828
 *****************************************************************************/
1829

1830
bool VirtualConsole::loadXML(QXmlStreamReader &root)
×
1831
{
1832
    if (root.name() != KXMLQLCVirtualConsole)
×
1833
    {
1834
        qWarning() << Q_FUNC_INFO << "Virtual Console node not found";
×
1835
        return false;
×
1836
    }
1837

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

1863
    return true;
1864
}
1865

1866
bool VirtualConsole::saveXML(QXmlStreamWriter *doc)
×
1867
{
1868
    Q_ASSERT(doc != NULL);
1869

1870
    /* Virtual Console entry */
1871
    doc->writeStartElement(KXMLQLCVirtualConsole);
×
1872

1873
    /* Contents */
1874
    Q_ASSERT(m_contents != NULL);
1875
    m_contents->saveXML(doc);
×
1876

1877
    /* Properties */
1878
    m_properties.saveXML(doc);
×
1879

1880
    /* End the <VirtualConsole> tag */
1881
    doc->writeEndElement();
×
1882

1883
    return true;
×
1884
}
1885

1886
QList<VCWidget *> VirtualConsole::getChildren(VCWidget *obj)
×
1887
{
1888
    QList<VCWidget *> list;
1889
    if (obj == NULL)
×
1890
        return list;
1891
    QListIterator <VCWidget*> it(obj->findChildren<VCWidget*>());
×
1892
    while (it.hasNext() == true)
×
1893
    {
1894
        VCWidget* child = it.next();
×
1895
        list.append(child);
×
1896
        list.append(getChildren(child));
×
1897
    }
1898
    return list;
1899
}
×
1900

1901
void VirtualConsole::postLoad()
×
1902
{
1903
    m_contents->postLoad();
×
1904

1905
    /* apply GM values
1906
      this should probably be placed in another place, but at the moment m_properties
1907
      is just loaded in VirtualConsole */
1908
    m_doc->inputOutputMap()->setGrandMasterValue(255);
×
1909
    m_doc->inputOutputMap()->setGrandMasterValueMode(m_properties.grandMasterValueMode());
×
1910
    m_doc->inputOutputMap()->setGrandMasterChannelMode(m_properties.grandMasterChannelMode());
×
1911

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

1936
    m_dockArea->setGrandMasterVisible(m_properties.grandMasterVisible());
×
1937
    m_dockArea->setGrandMasterInvertedAppearance(m_properties.grandMasterSliderMode());
×
1938

1939
    m_contents->setFocus();
×
1940

1941
    emit loaded();
×
1942
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc