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

mcallegari / qlcplus / 9573323472

18 Jun 2024 10:59PM UTC coverage: 32.056% (+0.02%) from 32.034%
9573323472

Pull #1586

github

web-flow
Merge e0912e5a0 into c1f5846de
Pull Request #1586: Introduce keyboard scroll flag in Virtual Console

25 of 34 new or added lines in 5 files covered. (73.53%)

1 existing line in 1 file now uncovered.

14042 of 43805 relevant lines covered (32.06%)

27030.04 hits per line

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

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

5
  Copyright (c) Heikki Junnila
6
                Massimo Callegari
7

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

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

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

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

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

61
#define SETTINGS_VC_SIZE "virtualconsole/size"
62

63
VirtualConsole* VirtualConsole::s_instance = NULL;
64

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

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

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

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

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

100
    , m_toolsSettingsAction(NULL)
101

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

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

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

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

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

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

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

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

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

141
    Q_ASSERT(doc != NULL);
142

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

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

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

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

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

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

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

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

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

191
    return m_latestWidgetId;
1✔
192
}
193

194
/*****************************************************************************
195
 * Properties
196
 *****************************************************************************/
197

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

203
/*****************************************************************************
204
 * Selected widget
205
 *****************************************************************************/
206

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

702
    return NULL;
703
}
704

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1023
        m_doc->setModified();
×
1024
    }
1025
}
×
1026

1027
/*****************************************************************************
1028
 * Edit menu callbacks
1029
 *****************************************************************************/
1030

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

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

1051
    updateActions();
×
1052
}
×
1053

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

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

1081
    VCWidget* parent;
1082
    VCWidget* widget;
1083
    QRect bounds;
×
1084

1085
    Q_ASSERT(contents() != NULL);
1086

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

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

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

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

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

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

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

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

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

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

1155
    updateActions();
×
1156
}
1157

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

1178
            if (parent != NULL)
×
1179
                disconnectWidgetFromParent(widget, parent);
×
1180

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

1187
        updateActions();
×
1188
    }
1189
    m_doc->setModified();
×
1190
}
×
1191

1192
void VirtualConsole::slotEditProperties()
×
1193
{
1194
    VCWidget* widget;
1195

1196
    Q_ASSERT(contents() != NULL);
1197

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

1203
    if (widget != NULL)
×
1204
        widget->editProperties();
×
1205
}
×
1206

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

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

1224
/*****************************************************************************
1225
 * Background menu callbacks
1226
 *****************************************************************************/
1227

1228
void VirtualConsole::slotBackgroundColor()
×
1229
{
1230
    QColor color;
×
1231

1232
    Q_ASSERT(contents() != NULL);
1233

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

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

1255
void VirtualConsole::slotBackgroundImage()
×
1256
{
1257
    QString path;
×
1258

1259
    Q_ASSERT(contents() != NULL);
1260

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

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

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

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

1301
/*****************************************************************************
1302
 * Foreground menu callbacks
1303
 *****************************************************************************/
1304

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

1309
    if (m_selectedWidgets.isEmpty() == true)
×
1310
        return;
×
1311

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

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

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

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

1334
/*****************************************************************************
1335
 * Font menu callbacks
1336
 *****************************************************************************/
1337

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

1343
    Q_ASSERT(contents() != NULL);
1344

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

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

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

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

1383
/*****************************************************************************
1384
 * Stacking menu callbacks
1385
 *****************************************************************************/
1386

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

1391
    if (m_selectedWidgets.isEmpty() == true)
×
1392
        return;
1393

1394
    VCWidget* widget;
1395
    foreach (widget, m_selectedWidgets)
×
1396
        widget->raise();
×
1397

1398
    m_doc->setModified();
×
1399
}
1400

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

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

1408
    VCWidget* widget;
1409
    foreach (widget, m_selectedWidgets)
×
1410
        widget->lower();
×
1411

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

1415
/*****************************************************************************
1416
 * Frame menu callbacks
1417
 *****************************************************************************/
1418

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

1423
    if (m_selectedWidgets.isEmpty() == true)
×
1424
        return;
1425

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

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

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

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

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

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

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

1455
/*****************************************************************************
1456
 * Dock area
1457
 *****************************************************************************/
1458

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

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

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

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

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

1479
/*****************************************************************************
1480
 * Contents
1481
 *****************************************************************************/
1482

1483
VCFrame* VirtualConsole::contents() const
781✔
1484
{
1485
    return m_contents;
781✔
1486
}
1487

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

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

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

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

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

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

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

1523
    /* Update actions' enabled status */
1524
    updateActions();
76✔
1525

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

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

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

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

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

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

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

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

1580
    return m_widgetsMap.value(id, NULL);
×
1581
}
1582

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

1587
    m_scrollArea = new VCScrollArea(this);
76✔
1588
    m_contentsLayout->addWidget(m_scrollArea);
76✔
1589
    m_scrollArea->setAlignment(Qt::AlignCenter);
76✔
1590
    m_scrollArea->setWidgetResizable(false);
76✔
1591

1592
    resetContents();
76✔
1593
}
76✔
1594

1595
/*****************************************************************************
1596
 * Key press handler
1597
 *****************************************************************************/
1598

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

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

1610
    event->accept();
1611
}
1612

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

1621
    QKeySequence seq(event->key() | event->modifiers());
×
1622
    emit keyReleased(seq);
×
1623

1624
    event->accept();
1625
}
1626

1627
/*****************************************************************************
1628
 * Main application mode
1629
 *****************************************************************************/
1630

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

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

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

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

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

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

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

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

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

1711
    // disable key passthru
1712
    m_scrollArea->setKeyPassthruEnabled(false);
80✔
1713

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

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

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

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

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

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

1766

1767
    // manage key passthru
1768
    m_scrollArea->setKeyPassthruEnabled(!m_keyboardScroll);
15✔
1769

1770
    // Hide toolbar; there's nothing usable there in operate mode
1771
    m_toolbar->hide();
15✔
1772

1773
    // Make sure the virtual console contents has the focus.
1774
    // Without this, key combinations don't work unless
1775
    // the user clicks on some VC area
1776
    m_contents->setFocus();
15✔
1777
}
15✔
1778

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

1810
/*****************************************************************************
1811
 * Load & Save
1812
 *****************************************************************************/
1813

1814
bool VirtualConsole::loadXML(QXmlStreamReader &root)
×
1815
{
1816
    if (root.name() != KXMLQLCVirtualConsole)
×
1817
    {
1818
        qWarning() << Q_FUNC_INFO << "Virtual Console node not found";
×
1819
        return false;
×
1820
    }
1821

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

1848
    return true;
1849
}
1850

1851
bool VirtualConsole::saveXML(QXmlStreamWriter *doc)
×
1852
{
1853
    Q_ASSERT(doc != NULL);
1854

1855
    /* Virtual Console entry */
1856
    doc->writeStartElement(KXMLQLCVirtualConsole);
×
1857

1858
    /* Contents */
1859
    Q_ASSERT(m_contents != NULL);
1860
    m_contents->saveXML(doc);
×
1861

1862
    /* Properties */
1863
    m_properties.saveXML(doc);
×
1864

1865
    /* End the <VirtualConsole> tag */
1866
    doc->writeEndElement();
×
1867

1868
    return true;
×
1869
}
1870

1871
QList<VCWidget *> VirtualConsole::getChildren(VCWidget *obj)
×
1872
{
1873
    QList<VCWidget *> list;
1874
    if (obj == NULL)
×
1875
        return list;
1876
    QListIterator <VCWidget*> it(obj->findChildren<VCWidget*>());
×
1877
    while (it.hasNext() == true)
×
1878
    {
1879
        VCWidget* child = it.next();
×
1880
        list.append(child);
×
1881
        list.append(getChildren(child));
×
1882
    }
1883
    return list;
1884
}
1885

1886
void VirtualConsole::postLoad()
×
1887
{
1888
    m_contents->postLoad();
×
1889

1890
    /* apply GM values
1891
      this should probably be placed in another place, but at the moment m_properties
1892
      is just loaded in VirtualConsole */
1893
    m_doc->inputOutputMap()->setGrandMasterValue(255);
×
1894
    m_doc->inputOutputMap()->setGrandMasterValueMode(m_properties.grandMasterValueMode());
×
1895
    m_doc->inputOutputMap()->setGrandMasterChannelMode(m_properties.grandMasterChannelMode());
×
1896

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

1921
    m_contents->setFocus();
×
1922

1923
    emit loaded();
×
1924
}
×
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