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

mcallegari / qlcplus / 7252848206

18 Dec 2023 07:26PM UTC coverage: 32.067% (+0.001%) from 32.066%
7252848206

push

github

mcallegari
Code style review #1427

199 of 628 new or added lines in 101 files covered. (31.69%)

8 existing lines in 2 files now uncovered.

15169 of 47304 relevant lines covered (32.07%)

23733.74 hits per line

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

44.97
/ui/src/virtualconsole/vcframe.cpp
1
/*
2
  Q Light Controller Plus
3
  vcframe.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 <QMapIterator>
24
#include <QMetaObject>
25
#include <QComboBox>
26
#include <QMessageBox>
27
#include <QSettings>
28
#include <QPainter>
29
#include <QAction>
30
#include <QStyle>
31
#include <QDebug>
32
#include <QPoint>
33
#include <QSize>
34
#include <QMenu>
35
#include <QFont>
36
#include <QList>
37

38
#include "vcframepageshortcut.h"
39
#include "vcpropertieseditor.h"
40
#include "vcframeproperties.h"
41
#include "vcaudiotriggers.h"
42
#include "virtualconsole.h"
43
#include "vcsoloframe.h"
44
#include "vcspeeddial.h"
45
#include "vccuelist.h"
46
#include "vcbutton.h"
47
#include "vcslider.h"
48
#include "vcmatrix.h"
49
#include "qlcfile.h"
50
#include "vcframe.h"
51
#include "vclabel.h"
52
#include "vcxypad.h"
53
#include "vcclock.h"
54
#include "apputil.h"
55
#include "doc.h"
56

57
const QSize VCFrame::defaultSize(QSize(200, 200));
58

59
const quint8 VCFrame::nextPageInputSourceId = 0;
60
const quint8 VCFrame::previousPageInputSourceId = 1;
61
const quint8 VCFrame::enableInputSourceId = 2;
62
const quint8 VCFrame::shortcutsBaseInputSourceId = 20;
63

64
VCFrame::VCFrame(QWidget* parent, Doc* doc, bool canCollapse)
95✔
65
    : VCWidget(parent, doc)
66
    , m_hbox(NULL)
67
    , m_collapseButton(NULL)
68
    , m_enableButton(NULL)
69
    , m_label(NULL)
70
    , m_collapsed(false)
71
    , m_showHeader(true)
72
    , m_showEnableButton(true)
73
    , m_multiPageMode(false)
74
    , m_currentPage(0)
75
    , m_totalPagesNumber(1)
76
    , m_nextPageBtn(NULL)
77
    , m_prevPageBtn(NULL)
78
    , m_pageCombo(NULL)
79
    , m_pagesLoop(false)
95✔
80
{
81
    /* Set the class name "VCFrame" as the object name as well */
82
    setObjectName(VCFrame::staticMetaObject.className());
95✔
83
    setFrameStyle(KVCFrameStyleSunken);
95✔
84
    setAllowChildren(true);
95✔
85
    setType(VCWidget::FrameWidget);
95✔
86

87
    if (canCollapse == true)
95✔
88
        createHeader();
3✔
89

90
    QSettings settings;
190✔
91
    QVariant var = settings.value(SETTINGS_FRAME_SIZE);
190✔
92
    if (var.isValid() == true)
95✔
93
        resize(var.toSize());
×
94
    else
95
        resize(defaultSize);
95✔
96
    m_width = this->width();
95✔
97
    m_height = this->height();
95✔
98
}
95✔
99

100
VCFrame::~VCFrame()
175✔
101
{
102
}
175✔
103

104
bool VCFrame::isBottomFrame()
13✔
105
{
106
    return (parentWidget() != NULL && qobject_cast<VCFrame*>(parentWidget()) == NULL);
13✔
107
}
108

109
void VCFrame::setDisableState(bool disable)
×
110
{
111
    if (m_enableButton)
×
112
    {
113
        m_enableButton->blockSignals(true);
×
114
        m_enableButton->setChecked(!disable);
×
115
        m_enableButton->blockSignals(false);
×
116
    }
117

118
    foreach (VCWidget* widget, this->findChildren<VCWidget*>())
×
119
    {
120
        widget->setDisableState(disable);
×
121
        if (!disable)
×
122
            widget->adjustIntensity(intensity());
×
123
    }
124

125
    m_disableState = disable;
×
126
    updateFeedback();
×
127
}
×
128

129
void VCFrame::setLiveEdit(bool liveEdit)
×
130
{
131
    if (m_doc->mode() == Doc::Design)
×
132
        return;
×
133

134
    m_liveEdit = liveEdit;
×
135

136
    if (!m_disableState)
×
137
        enableWidgetUI(!m_liveEdit);
×
138

139
    updateSubmasterValue();
×
140

141
    unsetCursor();
×
142
    update();
×
143
}
144

145
void VCFrame::setCaption(const QString& text)
5✔
146
{
147
    if (m_label != NULL)
5✔
148
    {
149
        if (!shortcuts().isEmpty() && m_currentPage < shortcuts().length())
1✔
150
        {
151
            // Show caption, if there is no page name
152
            if (m_pageShortcuts.at(m_currentPage)->name() == "")
×
153
                m_label->setText(text);
×
154
            else
155
            {
156
                // Show only page name, if there is no caption
157
                if (text == "")
×
158
                    m_label->setText(m_pageShortcuts.at(m_currentPage)->name());
×
159
                else
160
                    m_label->setText(text + " - " + m_pageShortcuts.at(m_currentPage)->name());
×
161
            }
162
        }
163
        else
164
            m_label->setText(text);
1✔
165
    }
166

167
    VCWidget::setCaption(text);
5✔
168
}
5✔
169

170
void VCFrame::setFont(const QFont &font)
×
171
{
172
    if (m_label != NULL)
×
173
    {
174
        m_label->setFont(font);
×
175
        m_hasCustomFont = true;
×
176
        m_doc->setModified();
×
177
    }
178
}
×
179

180
QFont VCFrame::font() const
×
181
{
182
    if (m_label != NULL)
×
183
        return m_label->font();
×
184
    else
185
        return VCWidget::font();
×
186
}
187

188
void VCFrame::setForegroundColor(const QColor &color)
×
189
{
190
    if (m_label != NULL)
×
191
    {
192
        m_label->setStyleSheet("QLabel { background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #666666, stop: 1 #000000); "
×
193
                               "color: " + color.name() + "; border-radius: 3px; padding: 3px; margin-left: 2px; }");
×
194
        m_hasCustomForegroundColor = true;
×
195
        m_doc->setModified();
×
196
    }
197
}
×
198

199
QColor VCFrame::foregroundColor() const
×
200
{
201
    if (m_label != NULL)
×
202
        return m_label->palette().color(m_label->foregroundRole());
×
203
    else
204
        return VCWidget::foregroundColor();
×
205
}
206

207
void VCFrame::setHeaderVisible(bool enable)
2✔
208
{
209
    m_showHeader = enable;
2✔
210

211
    if (m_hbox == NULL)
2✔
212
        createHeader();
1✔
213

214
    if (enable == false)
2✔
215
    {
216
        m_collapseButton->hide();
×
217
        m_label->hide();
×
218
        m_enableButton->hide();
×
219
    }
220
    else
221
    {
222
        m_collapseButton->show();
2✔
223
        m_label->show();
2✔
224
        if (m_showEnableButton)
2✔
225
            m_enableButton->show();
2✔
226
    }
227
}
2✔
228

229
bool VCFrame::isHeaderVisible() const
4✔
230
{
231
    return m_showHeader;
4✔
232
}
233

234
void VCFrame::setEnableButtonVisible(bool show)
2✔
235
{
236
    if (show && m_showHeader) m_enableButton->show();
2✔
237
    else m_enableButton->hide();
×
238

239
    m_showEnableButton = show;
2✔
240
}
2✔
241

242
bool VCFrame::isEnableButtonVisible() const
3✔
243
{
244
    return m_showEnableButton;
3✔
245
}
246

247
bool VCFrame::isCollapsed() const
6✔
248
{
249
    return m_collapsed;
6✔
250
}
251

252
QSize VCFrame::originalSize() const
×
253
{
254
    return QSize(m_width, m_height);
×
255
}
256

257
void VCFrame::slotCollapseButtonToggled(bool toggle)
×
258
{
259
    if (toggle == true)
×
260
    {
261
        m_width = this->width();
×
262
        m_height = this->height();
×
263
        if (m_multiPageMode == true)
×
264
        {
265
            if (m_prevPageBtn) m_prevPageBtn->hide();
×
266
            if (m_nextPageBtn) m_nextPageBtn->hide();
×
267
        }
268
        resize(QSize(200, 40));
×
269
        m_collapsed = true;
×
270
    }
271
    else
272
    {
273
        resize(QSize(m_width, m_height));
×
274
        if (m_multiPageMode == true)
×
275
        {
276
            if (m_prevPageBtn) m_prevPageBtn->show();
×
277
            if (m_nextPageBtn) m_nextPageBtn->show();
×
278
        }
279
        m_collapsed = false;
×
280
    }
281
    m_doc->setModified();
×
282
}
×
283

284
void VCFrame::slotEnableButtonClicked(bool checked)
×
285
{
286
    setDisableState(!checked);
×
287
}
×
288

289
void VCFrame::createHeader()
4✔
290
{
291
    if (m_hbox != NULL)
4✔
292
        return;
×
293

294
    QVBoxLayout *vbox = new QVBoxLayout(this);
4✔
295
    /* Main HBox */
296
    m_hbox = new QHBoxLayout();
4✔
297
    m_hbox->setGeometry(QRect(0, 0, 200, 40));
4✔
298

299
    layout()->setSpacing(2);
4✔
300
    layout()->setContentsMargins(4, 4, 4, 4);
4✔
301
    layout()->addItem(m_hbox);
4✔
302
    vbox->addStretch();
4✔
303

304
    m_collapseButton = new QToolButton(this);
4✔
305
    m_collapseButton->setStyle(AppUtil::saneStyle());
4✔
306
    m_collapseButton->setIconSize(QSize(32, 32));
4✔
307
    m_collapseButton->setMinimumSize(QSize(32, 32));
4✔
308
    m_collapseButton->setMaximumSize(QSize(32, 32));
4✔
309
    m_collapseButton->setIcon(QIcon(":/expand.png"));
4✔
310
    m_collapseButton->setCheckable(true);
4✔
311
    QString cBtnSS = "QToolButton { background-color: #E0DFDF; border: 1px solid gray; border-radius: 3px; padding: 3px; } ";
8✔
312
    cBtnSS += "QToolButton:pressed { background-color: #919090; border: 1px solid gray; border-radius: 3px; padding: 3px; } ";
4✔
313
    m_collapseButton->setStyleSheet(cBtnSS);
4✔
314

315
    m_hbox->addWidget(m_collapseButton);
4✔
316
    connect(m_collapseButton, SIGNAL(toggled(bool)), this, SLOT(slotCollapseButtonToggled(bool)));
4✔
317

318
    m_label = new QLabel(this);
4✔
319
    m_label->setText(this->caption());
4✔
320
    QString txtColor = "white";
8✔
321
    if (m_hasCustomForegroundColor)
4✔
322
        txtColor = this->foregroundColor().name();
×
323
    m_label->setStyleSheet("QLabel { background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #666666, stop: 1 #000000); "
4✔
324
                           "color: " + txtColor + "; border-radius: 3px; padding: 3px; margin-left: 2px; margin-right: 2px; }");
8✔
325

326
    if (m_hasCustomFont)
4✔
327
        m_label->setFont(font());
×
328
    else
329
    {
330
        QFont m_font = QApplication::font();
8✔
331
        m_font.setBold(true);
4✔
332
        m_font.setPixelSize(12);
4✔
333
        m_label->setFont(m_font);
4✔
334
    }
335
    m_hbox->addWidget(m_label);
4✔
336

337
    m_enableButton = new QToolButton(this);
4✔
338
    m_enableButton->setStyle(AppUtil::saneStyle());
4✔
339
    m_enableButton->setIconSize(QSize(32, 32));
4✔
340
    m_enableButton->setMinimumSize(QSize(32, 32));
4✔
341
    m_enableButton->setMaximumSize(QSize(32, 32));
4✔
342
    m_enableButton->setIcon(QIcon(":/check.png"));
4✔
343
    m_enableButton->setCheckable(true);
4✔
344
    QString eBtnSS = "QToolButton { background-color: #E0DFDF; border: 1px solid gray; border-radius: 3px; padding: 3px; } ";
4✔
345
    eBtnSS += "QToolButton:checked { background-color: #D7DE75; border: 1px solid gray; border-radius: 3px; padding: 3px; } ";
4✔
346
    m_enableButton->setStyleSheet(eBtnSS);
4✔
347
    m_enableButton->setEnabled(true);
4✔
348
    m_enableButton->setChecked(true);
4✔
349
    if (!m_showEnableButton)
4✔
350
        m_enableButton->hide();
×
351

352
    m_hbox->addWidget(m_enableButton);
4✔
353
    connect(m_enableButton, SIGNAL(clicked(bool)), this, SLOT(slotEnableButtonClicked(bool)));
4✔
354
}
355

356
/*********************************************************************
357
 * Pages
358
 *********************************************************************/
359

360
void VCFrame::setMultipageMode(bool enable)
2✔
361
{
362
    if (m_multiPageMode == enable)
2✔
363
        return;
2✔
364

365
    if (enable == true)
×
366
    {
367
        if (m_prevPageBtn != NULL && m_nextPageBtn != NULL && m_pageCombo != NULL)
×
368
            return;
×
369

370
        QString btnSS = "QToolButton { background-color: #E0DFDF; border: 1px solid gray; border-radius: 3px; padding: 3px; margin-left: 2px; }";
×
371
        btnSS += "QToolButton:pressed { background-color: #919090; border: 1px solid gray; border-radius: 3px; padding: 3px; margin-left: 2px; }";
×
372

373
        m_prevPageBtn = new QToolButton(this);
×
374
        m_prevPageBtn->setStyle(AppUtil::saneStyle());
×
375
        m_prevPageBtn->setIconSize(QSize(32, 32));
×
376
        m_prevPageBtn->setMinimumSize(QSize(32, 32));
×
377
        m_prevPageBtn->setMaximumSize(QSize(32, 32));
×
378
        m_prevPageBtn->setIcon(QIcon(":/back.png"));
×
379
        m_prevPageBtn->setStyleSheet(btnSS);
×
380
        m_hbox->addWidget(m_prevPageBtn);
×
381

382
        m_pageCombo = new QComboBox(this);
×
383
        m_pageCombo->setMaximumWidth(100);
×
384
        m_pageCombo->setFixedHeight(32);
×
385
        m_pageCombo->setFocusPolicy(Qt::NoFocus);
×
386

387
        /** Add a single shortcut until setTotalPagesNumber kicks in */
388
        addShortcut();
×
389

390
        m_pageCombo->setStyleSheet("QComboBox { background-color: black; color: red; margin-left: 2px; padding: 3px; }");
×
391
        if (m_hasCustomFont)
×
392
        {
393
            m_pageCombo->setFont(font());
×
394
        }
395
        else
396
        {
397
            QFont m_font = QApplication::font();
×
398
            m_font.setBold(true);
×
399
            m_font.setPixelSize(12);
×
400
            m_pageCombo->setFont(m_font);
×
401
        }
402
        m_hbox->addWidget(m_pageCombo);
×
403

404
        m_nextPageBtn = new QToolButton(this);
×
405
        m_nextPageBtn->setStyle(AppUtil::saneStyle());
×
406
        m_nextPageBtn->setIconSize(QSize(32, 32));
×
407
        m_nextPageBtn->setMinimumSize(QSize(32, 32));
×
408
        m_nextPageBtn->setMaximumSize(QSize(32, 32));
×
409
        m_nextPageBtn->setIcon(QIcon(":/forward.png"));
×
410
        m_nextPageBtn->setStyleSheet(btnSS);
×
411
        m_hbox->addWidget(m_nextPageBtn);
×
412

413
        connect (m_prevPageBtn, SIGNAL(clicked()), this, SLOT(slotPreviousPage()));
×
414
        connect (m_pageCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(slotSetPage(int)));
×
415
        connect (m_nextPageBtn, SIGNAL(clicked()), this, SLOT(slotNextPage()));
×
416

NEW
417
        if (this->isCollapsed() == false)
×
418
        {
419
            m_prevPageBtn->show();
×
420
            m_nextPageBtn->show();
×
421
        }
422
        else
423
        {
424
            m_prevPageBtn->hide();
×
425
            m_nextPageBtn->hide();
×
426
        }
427
        m_pageCombo->show();
×
428

429
        if (m_pagesMap.isEmpty())
×
430
        {
431
            QListIterator <VCWidget*> it(this->findChildren<VCWidget*>());
×
432
            while (it.hasNext() == true)
×
433
            {
434
                VCWidget* child = it.next();
×
435
                addWidgetToPageMap(child);
×
436
            }
437
        }
438
    }
439
    else
440
    {
441
        if (m_prevPageBtn == NULL && m_nextPageBtn == NULL && m_pageCombo == NULL)
×
442
            return;
×
443

444
        resetShortcuts();
×
445
        m_hbox->removeWidget(m_prevPageBtn);
×
446
        m_hbox->removeWidget(m_pageCombo);
×
447
        m_hbox->removeWidget(m_nextPageBtn);
×
448
        delete m_prevPageBtn;
×
449
        delete m_pageCombo;
×
450
        delete m_nextPageBtn;
×
451
        m_prevPageBtn = NULL;
×
452
        m_pageCombo = NULL;
×
453
        m_nextPageBtn = NULL;
×
454
        setCaption(caption());
×
455
    }
456

457
    m_multiPageMode = enable;
×
458
}
459

460
bool VCFrame::multipageMode() const
7✔
461
{
462
    return m_multiPageMode;
7✔
463
}
464

465
void VCFrame::setTotalPagesNumber(int num)
2✔
466
{
467
    if (num == m_totalPagesNumber)
2✔
468
        return;
2✔
469

470
    if (num < m_totalPagesNumber)
×
471
    {
472
        for (int i = 0; i < (m_totalPagesNumber - num); i++)
×
473
        {
474
            m_pageShortcuts.removeLast();
×
475
            if (m_pageCombo)
×
476
                m_pageCombo->removeItem(m_pageCombo->count() - 1);
×
477
        }
478
    }
479
    else
480
    {
481
        for (int i = 0; i < (num - m_totalPagesNumber); i++)
×
482
            addShortcut();
×
483
    }
484
    m_totalPagesNumber = num;
×
485
}
486

487
int VCFrame::totalPagesNumber()
2✔
488
{
489
    return m_totalPagesNumber;
2✔
490
}
491

492
int VCFrame::currentPage()
1✔
493
{
494
    if (m_multiPageMode == false)
1✔
495
        return 0;
1✔
496
    return m_currentPage;
×
497
}
498

499
void VCFrame::updatePageCombo()
2✔
500
{
501
    if (m_pageCombo == NULL || shortcuts().isEmpty())
2✔
502
        return;
2✔
503

504
    // Save current page to restore it afterwards
505
    int page = currentPage();
×
506
    m_pageCombo->blockSignals(true);
×
507
    m_pageCombo->clear();
×
508
    for (int i = 0; i < m_pageShortcuts.count(); i++)
×
509
        m_pageCombo->addItem(m_pageShortcuts.at(i)->name());
×
510
    m_pageCombo->setCurrentIndex(page);
×
511
    m_pageCombo->blockSignals(false);
×
512
}
513

514
/*********************************************************************
515
 * Shortcuts
516
 *********************************************************************/
517

518
void VCFrame::addShortcut()
×
519
{
520
    int index = m_pageShortcuts.count();
×
521
    m_pageShortcuts.append(new VCFramePageShortcut(index, VCFrame::shortcutsBaseInputSourceId + index));
×
522
    m_pageCombo->addItem(m_pageShortcuts.last()->name());
×
523
}
×
524

525
void VCFrame::setShortcuts(QList<VCFramePageShortcut *> shortcuts)
2✔
526
{
527
    resetShortcuts();
2✔
528
    foreach (VCFramePageShortcut const* shortcut, shortcuts)
2✔
529
    {
530
        m_pageShortcuts.append(new VCFramePageShortcut(*shortcut));
×
531
        if (shortcut->m_inputSource != NULL)
×
532
            setInputSource(shortcut->m_inputSource, shortcut->m_id);
×
533
    }
534
    updatePageCombo();
2✔
535
}
2✔
536

537
void VCFrame::resetShortcuts()
2✔
538
{
539
    int count = m_pageShortcuts.count();
2✔
540
    for (int i = 0; i < count; i++)
2✔
541
    {
542
        VCFramePageShortcut* shortcut = m_pageShortcuts.takeLast();
×
543
        delete shortcut;
×
544
    }
545
    m_pageShortcuts.clear();
2✔
546
}
2✔
547

548
QList<VCFramePageShortcut*> VCFrame::shortcuts() const
3✔
549
{
550
    return m_pageShortcuts;
3✔
551
}
552

553
void VCFrame::setPagesLoop(bool pagesLoop)
2✔
554
{
555
    m_pagesLoop = pagesLoop;
2✔
556
}
2✔
557

558
bool VCFrame::pagesLoop() const
1✔
559
{
560
    return m_pagesLoop;
1✔
561
}
562

563
void VCFrame::addWidgetToPageMap(VCWidget *widget)
8✔
564
{
565
    m_pagesMap.insert(widget, widget->page());
8✔
566
}
8✔
567

568
void VCFrame::removeWidgetFromPageMap(VCWidget *widget)
×
569
{
570
    m_pagesMap.remove(widget);
×
571
}
×
572

573
void VCFrame::slotPreviousPage()
×
574
{
575
    if (m_pagesLoop && m_currentPage == 0)
×
576
        slotSetPage(m_totalPagesNumber - 1);
×
577
    else
578
        slotSetPage(m_currentPage - 1);
×
579
    sendFeedback(m_currentPage, previousPageInputSourceId);
×
580
}
×
581

582
void VCFrame::slotNextPage()
×
583
{
584
    if (m_pagesLoop && m_currentPage == m_totalPagesNumber - 1)
×
585
        slotSetPage(0);
×
586
    else
587
        slotSetPage(m_currentPage + 1);
×
588

589
    sendFeedback(m_currentPage, nextPageInputSourceId);
×
590
}
×
591

592
void VCFrame::slotSetPage(int pageNum)
1✔
593
{
594
    if (m_pageCombo)
1✔
595
    {
596
        if (pageNum >= 0 && pageNum < m_totalPagesNumber)
×
597
            m_currentPage = pageNum;
×
598

599
        m_pageCombo->blockSignals(true);
×
600
        m_pageCombo->setCurrentIndex(m_currentPage);
×
601
        m_pageCombo->blockSignals(false);
×
602
        setCaption(caption());
×
603

604
        QMapIterator <VCWidget*, int> it(m_pagesMap);
×
605
        while (it.hasNext() == true)
×
606
        {
607
            it.next();
×
608
            int page = it.value();
×
609
            VCWidget *widget = it.key();
×
610
            if (page == m_currentPage)
×
611
            {
612
                widget->setEnabled(true);
×
613
                widget->show();
×
614
                widget->updateFeedback();
×
615
            }
616
            else
617
            {
618
                widget->setEnabled(false);
×
619
                widget->hide();
×
620
            }
621
        }
622
        m_doc->setModified();
×
623
        emit pageChanged(m_currentPage);
×
624
    }
625
    updateFeedback();
1✔
626
}
1✔
627

628
void VCFrame::slotModeChanged(Doc::Mode mode)
21✔
629
{
630
    if (mode == Doc::Operate)
21✔
631
    {
632
        if (isDisabled())
16✔
633
            slotEnableButtonClicked(false);
×
634
        updateSubmasterValue();
16✔
635
        updateFeedback();
16✔
636
    }
637

638
    VCWidget::slotModeChanged(mode);
21✔
639
}
21✔
640

641
/*********************************************************************
642
 * Submasters
643
 *********************************************************************/
644

645
void VCFrame::slotSubmasterValueChanged(qreal value)
×
646
{
647
    qDebug() << Q_FUNC_INFO << "val:" << value;
×
648
    VCSlider *submaster = qobject_cast<VCSlider *>(sender());
×
649
    QListIterator <VCWidget*> it(this->findChildren<VCWidget*>());
×
650
    while (it.hasNext() == true)
×
651
    {
652
        VCWidget *child = it.next();
×
653
        if (child->parent() == this && child != submaster)
×
654
            child->adjustIntensity(value);
×
655
    }
656
}
×
657

658
void VCFrame::updateSubmasterValue()
16✔
659
{
660
    QListIterator <VCWidget*> it(this->findChildren<VCWidget*>());
48✔
661
    while (it.hasNext() == true)
18✔
662
    {
663
        VCWidget* child = it.next();
2✔
664
        if (child->parent() == this && child->type() == SliderWidget)
2✔
665
        {
666
            VCSlider* slider = reinterpret_cast<VCSlider*>(child);
×
667
            if (slider->sliderMode() == VCSlider::Submaster)
×
668
                slider->emitSubmasterValue();
×
669
        }
670
    }
671
}
16✔
672

673
void VCFrame::adjustIntensity(qreal val)
×
674
{
675
    VCWidget::adjustIntensity(val);
×
676

677
    if (isDisabled())
×
678
        return;
×
679

680
    QListIterator <VCWidget*> it(this->findChildren<VCWidget*>());
×
681
    while (it.hasNext() == true)
×
682
    {
683
        VCWidget *child = it.next();
×
684
        if (child->parent() == this)
×
685
            child->adjustIntensity(val);
×
686
    }
687
}
688

689
/*****************************************************************************
690
 * Key Sequences
691
 *****************************************************************************/
692

693
void VCFrame::setEnableKeySequence(const QKeySequence &keySequence)
2✔
694
{
695
    m_enableKeySequence = QKeySequence(keySequence);
2✔
696
}
2✔
697

698
QKeySequence VCFrame::enableKeySequence() const
1✔
699
{
700
    return m_enableKeySequence;
1✔
701
}
702

703
void VCFrame::setNextPageKeySequence(const QKeySequence& keySequence)
2✔
704
{
705
    m_nextPageKeySequence = QKeySequence(keySequence);
2✔
706
}
2✔
707

708
QKeySequence VCFrame::nextPageKeySequence() const
1✔
709
{
710
    return m_nextPageKeySequence;
1✔
711
}
712

713
void VCFrame::setPreviousPageKeySequence(const QKeySequence& keySequence)
2✔
714
{
715
    m_previousPageKeySequence = QKeySequence(keySequence);
2✔
716
}
2✔
717

718
QKeySequence VCFrame::previousPageKeySequence() const
1✔
719
{
720
    return m_previousPageKeySequence;
1✔
721
}
722

723
void VCFrame::slotKeyPressed(const QKeySequence& keySequence)
×
724
{
725
    if (isEnabled() == false)
×
726
        return;
×
727

728
    if (m_enableKeySequence == keySequence)
×
729
        setDisableState(!isDisabled());
×
730
    else if (m_previousPageKeySequence == keySequence)
×
731
        slotPreviousPage();
×
732
    else if (m_nextPageKeySequence == keySequence)
×
733
        slotNextPage();
×
734
    else
735
    {
736
        foreach (VCFramePageShortcut* shortcut, m_pageShortcuts)
×
737
        {
738
            if (shortcut->m_keySequence == keySequence)
×
739
                slotSetPage(shortcut->m_page);
×
740
        }
741
    }
742
}
743

744
void VCFrame::updateFeedback()
17✔
745
{
746
    QSharedPointer<QLCInputSource> src = inputSource(enableInputSourceId);
34✔
747
    if (!src.isNull() && src->isValid() == true)
17✔
748
    {
749
        if (m_disableState == false)
×
750
        {
751
            sendFeedback(src->upperValue(), enableInputSourceId);
×
752
        }
753
        else
754
        {
755
            // temporarily revert the disabled state otherwise this
756
            // feedback will never go through (cause of acceptsInput)
757
            m_disableState = false;
×
758
            sendFeedback(src->lowerValue(), enableInputSourceId);
×
759
            m_disableState = true;
×
760
        }
761
    }
762

763
    foreach (VCFramePageShortcut* shortcut, m_pageShortcuts)
17✔
764
    {
765
        QSharedPointer<QLCInputSource> src = shortcut->m_inputSource;
×
766
        if (!src.isNull() && src->isValid() == true)
×
767
        {
768
            if (m_currentPage == shortcut->m_page)
×
769
                sendFeedback(src->upperValue(), src);
×
770
            else
771
                sendFeedback(src->lowerValue(), src);
×
772
        }
773
    }
774

775
    QListIterator <VCWidget*> it(this->findChildren<VCWidget*>());
51✔
776
    while (it.hasNext() == true)
19✔
777
    {
778
        VCWidget* child = it.next();
2✔
779
        if (child->parent() == this)
2✔
780
            child->updateFeedback();
2✔
781
    }
782
}
17✔
783

784
/*****************************************************************************
785
 * External input
786
 *****************************************************************************/
787

788
void VCFrame::slotInputValueChanged(quint32 universe, quint32 channel, uchar value)
×
789
{
790
    if (isEnabled() == false)
×
791
        return;
×
792

793
    quint32 pagedCh = (page() << 16) | channel;
×
794

795
    if (checkInputSource(universe, pagedCh, value, sender(), enableInputSourceId) && value)
×
796
        setDisableState(!isDisabled());
×
797
    else if (checkInputSource(universe, pagedCh, value, sender(), previousPageInputSourceId) && value)
×
798
        slotPreviousPage();
×
799
    else if (checkInputSource(universe, pagedCh, value, sender(), nextPageInputSourceId) && value)
×
800
        slotNextPage();
×
801
    else
802
    {
803
        foreach (VCFramePageShortcut* shortcut, m_pageShortcuts)
×
804
        {
805
            if (shortcut->m_inputSource != NULL &&
×
806
                    shortcut->m_inputSource->universe() == universe &&
×
807
                    shortcut->m_inputSource->channel() == pagedCh)
×
808
            {
809
                slotSetPage(shortcut->m_page);
×
810
            }
811
        }
812
    }
813
}
814

815
/*****************************************************************************
816
 * Clipboard
817
 *****************************************************************************/
818

819
VCWidget* VCFrame::createCopy(VCWidget* parent)
1✔
820
{
821
    Q_ASSERT(parent != NULL);
1✔
822

823
    VCFrame* frame = new VCFrame(parent, m_doc, true);
1✔
824
    if (frame->copyFrom(this) == false)
1✔
825
    {
826
        delete frame;
×
827
        frame = NULL;
×
828
    }
829

830
    return frame;
1✔
831
}
832

833
bool VCFrame::copyFrom(const VCWidget* widget)
2✔
834
{
835
    const VCFrame* frame = qobject_cast<const VCFrame*> (widget);
2✔
836
    if (frame == NULL)
2✔
837
        return false;
1✔
838

839
    setHeaderVisible(frame->m_showHeader);
1✔
840
    setEnableButtonVisible(frame->m_showEnableButton);
1✔
841

842
    setMultipageMode(frame->m_multiPageMode);
1✔
843
    setTotalPagesNumber(frame->m_totalPagesNumber);
1✔
844

845
    setPagesLoop(frame->m_pagesLoop);
1✔
846

847
    setEnableKeySequence(frame->m_enableKeySequence);
1✔
848
    setNextPageKeySequence(frame->m_nextPageKeySequence);
1✔
849
    setPreviousPageKeySequence(frame->m_previousPageKeySequence);
1✔
850
    setShortcuts(frame->shortcuts());
1✔
851

852
    QListIterator <VCWidget*> it(widget->findChildren<VCWidget*>());
3✔
853
    while (it.hasNext() == true)
2✔
854
    {
855
        VCWidget* child = it.next();
1✔
856
        VCWidget* childCopy = NULL;
1✔
857

858
        /* findChildren() is recursive, so the list contains all
859
           possible child widgets below this frame. Each frame must
860
           save only its direct children to preserve hierarchy, so
861
           save only such widgets that have this widget as their
862
           direct parent. */
863
        if (child->parentWidget() == widget)
1✔
864
        {
865
            childCopy = child->createCopy(this);
1✔
866
            VirtualConsole::instance()->addWidgetInMap(childCopy);
1✔
867

868
            qDebug() << "Child copy in parent:" << childCopy->caption() << ", page:" << childCopy->page();
1✔
869
        }
870

871
        if (childCopy != NULL)
1✔
872
        {
873
            addWidgetToPageMap(childCopy);
1✔
874

875
            if (childCopy->type() == VCWidget::SliderWidget)
1✔
876
            {
877
                VCSlider *slider = qobject_cast<VCSlider*>(childCopy);
×
878
                // always connect a slider as it it was a submaster
879
                // cause this signal is emitted only when a slider is
880
                // a submaster
881
                connect(slider, SIGNAL(submasterValueChanged(qreal)),
×
882
                        this, SLOT(slotSubmasterValueChanged(qreal)));
883
            }
884
        }
885
    }
886

887
    if (m_multiPageMode)
1✔
888
        slotSetPage(frame->m_currentPage);
×
889

890
    /* Copy common stuff */
891
    return VCWidget::copyFrom(widget);
1✔
892
}
893

894
/*****************************************************************************
895
 * Properties
896
 *****************************************************************************/
897

898
void VCFrame::applyProperties(VCFrameProperties const& prop)
×
899
{
900
    if (multipageMode() == true && prop.cloneWidgets() == true && m_pagesMap.isEmpty() == false)
×
901
    {
902
        for (int pg = 1; pg < totalPagesNumber(); pg++)
×
903
        {
904
            QListIterator <VCWidget*> it(this->findChildren<VCWidget*>());
×
905
            while (it.hasNext() == true)
×
906
            {
907
                VCWidget* child = it.next();
×
908
                if (child->page() == 0 && child->parentWidget() == this)
×
909
                {
910
                    VCWidget *newWidget = child->createCopy(this);
×
911
                    VirtualConsole::instance()->addWidgetInMap(newWidget);
×
912
                    //qDebug() << "Cloning:" << newWidget->caption() << ", copy page:" << newWidget->page() << ", page to set:" << pg;
913
                    newWidget->setPage(pg);
×
914
                    newWidget->remapInputSources(pg);
×
915
                    newWidget->show();
×
916

917
                    bool multiPageFrame = false;
×
918
                    if (newWidget->type() == VCWidget::FrameWidget || newWidget->type() == VCWidget::SoloFrameWidget)
×
919
                    {
920
                        VCFrame *fr = qobject_cast<VCFrame *>(newWidget);
×
921
                        multiPageFrame = fr->multipageMode();
×
922
                    }
923
                    /** If the cloned widget is again a multipage frame, then there's not much
924
                     *  that can be done to distinguish nested pages, so we leave the children
925
                     *  mapping as it is */
926
                    if (multiPageFrame == false)
×
927
                    {
928
                        /**
929
                         *  Remap input sources to the new page, otherwise
930
                         *  all the cloned widgets would respond to the
931
                         *  same controls
932
                         */
933
                        foreach (VCWidget* widget, newWidget->findChildren<VCWidget*>())
×
934
                        {
935
                            //qDebug() << "Child" << widget->caption() << ", page:" << widget->page() << ", new page:" << pg;
936
                            widget->setPage(pg);
×
937
                            widget->remapInputSources(pg);
×
938
                        }
939
                    }
940

941
                    addWidgetToPageMap(newWidget);
×
942
                }
943
            }
944
        }
945
        slotSetPage(0);
×
946
    }
947
    else if (multipageMode() == false)
×
948
    {
949
        setTotalPagesNumber(1);
×
950
        resize(QSize(this->width(), this->height()));
×
951

952
        QMapIterator <VCWidget*, int> it(m_pagesMap);
×
953
        while (it.hasNext() == true)
×
954
        {
955
            it.next();
×
956
            int page = it.value();
×
957
            VCWidget *widget = it.key();
×
958
            if (page > 0)
×
959
            {
960
                removeWidgetFromPageMap(widget);
×
961
                delete widget;
×
962
            }
963
            else
964
            {
965
                widget->setEnabled(true);
×
966
                widget->show();
×
967
                widget->updateFeedback();
×
968
            }
969
        }
970
    }
971
    VirtualConsole* vc = VirtualConsole::instance();
×
972
    if (vc != NULL)
×
973
        vc->reselectWidgets();
×
974
}
×
975

976
void VCFrame::editProperties()
×
977
{
978
    if (isBottomFrame() == true)
×
979
        return;
×
980

981
    VCFrameProperties prop(NULL, this, m_doc);
×
982
    if (prop.exec() == QDialog::Accepted)
×
983
    {
984
        applyProperties(prop);
×
985
    }
986
}
987

988
/*****************************************************************************
989
 * Load & Save
990
 *****************************************************************************/
991

992
bool VCFrame::loadXML(QXmlStreamReader &root)
4✔
993
{
994
    bool disableState = false;
4✔
995

996
    if (root.name() != xmlTagName())
4✔
997
    {
998
        qWarning() << Q_FUNC_INFO << "Frame node not found";
1✔
999
        return false;
1✔
1000
    }
1001

1002
    /* Widget commons */
1003
    loadXMLCommon(root);
3✔
1004

1005
    // Sorted list for new shortcuts
1006
    QList<VCFramePageShortcut *> newShortcuts;
3✔
1007

1008
    /* Children */
1009
    while (root.readNextStartElement())
14✔
1010
    {
1011
        /*
1012
        qDebug() << "VC Frame <" << caption() << "> tag:" << root.name();
1013
        if (root.attributes().hasAttribute("Caption"))
1014
            qDebug() << "Widget caption:" << root.attributes().value("Caption").toString();
1015
        */
1016

1017
        if (root.name() == KXMLQLCWindowState)
11✔
1018
        {
1019
            /* Frame geometry (visibility is ignored) */
1020
            int x = 0, y = 0, w = 0, h = 0;
1✔
1021
            bool visible = false;
1✔
1022
            loadXMLWindowState(root, &x, &y, &w, &h, &visible);
1✔
1023
            setGeometry(x, y, w, h);
1✔
1024
            m_width = w;
1✔
1025
            m_height = h;
1✔
1026
        }
1027
        else if (root.name() == KXMLQLCVCWidgetAppearance)
10✔
1028
        {
1029
            /* Frame appearance */
1030
            loadXMLAppearance(root);
×
1031
        }
1032
        else if (root.name() == KXMLQLCVCFrameAllowChildren)
10✔
1033
        {
1034
            /* Allow children */
1035
            if (root.readElementText() == KXMLQLCTrue)
1✔
1036
                setAllowChildren(true);
×
1037
            else
1038
                setAllowChildren(false);
1✔
1039
        }
1040
        else if (root.name() == KXMLQLCVCFrameAllowResize)
9✔
1041
        {
1042
            /* Allow resize */
1043
            if (root.readElementText() == KXMLQLCTrue)
1✔
1044
                setAllowResize(true);
×
1045
            else
1046
                setAllowResize(false);
1✔
1047
        }
1048
        else if (root.name() == KXMLQLCVCFrameIsCollapsed)
8✔
1049
        {
1050
            /* Collapsed */
1051
            if (root.readElementText() == KXMLQLCTrue && m_collapseButton != NULL)
×
1052
                m_collapseButton->toggle();
×
1053
        }
1054
        else if (root.name() == KXMLQLCVCFrameIsDisabled)
8✔
1055
        {
1056
            /* Enabled */
1057
            if (root.readElementText() == KXMLQLCTrue)
×
1058
                disableState = true;
×
1059
        }
1060
        else if (root.name() == KXMLQLCVCFrameShowHeader)
8✔
1061
        {
1062
            if (root.readElementText() == KXMLQLCTrue)
×
1063
                setHeaderVisible(true);
×
1064
            else
1065
                setHeaderVisible(false);
×
1066
        }
1067
        else if (root.name() == KXMLQLCVCFrameShowEnableButton)
8✔
1068
        {
1069
            if (root.readElementText() == KXMLQLCTrue)
×
1070
                setEnableButtonVisible(true);
×
1071
            else
1072
                setEnableButtonVisible(false);
×
1073
        }
1074
        else if (root.name() == KXMLQLCVCSoloFrameMixing && this->type() == SoloFrameWidget)
8✔
1075
        {
1076
            if (root.readElementText() == KXMLQLCTrue)
×
1077
                reinterpret_cast<VCSoloFrame*>(this)->setSoloframeMixing(true);
×
1078
            else
1079
                reinterpret_cast<VCSoloFrame*>(this)->setSoloframeMixing(false);
×
1080
        }
1081
        else if (root.name() == KXMLQLCVCFrameMultipage)
8✔
1082
        {
1083
            setMultipageMode(true);
×
1084
            QXmlStreamAttributes attrs = root.attributes();
×
1085
            if (attrs.hasAttribute(KXMLQLCVCFramePagesNumber))
×
1086
                setTotalPagesNumber(attrs.value(KXMLQLCVCFramePagesNumber).toString().toInt());
×
1087

NEW
1088
            if (attrs.hasAttribute(KXMLQLCVCFrameCurrentPage))
×
1089
                slotSetPage(attrs.value(KXMLQLCVCFrameCurrentPage).toString().toInt());
×
1090
            root.skipCurrentElement();
×
1091
        }
1092
        else if (root.name() == KXMLQLCVCFrameEnableSource)
8✔
1093
        {
1094
            QString str = loadXMLSources(root, enableInputSourceId);
×
1095
            if (str.isEmpty() == false)
×
1096
                setEnableKeySequence(stripKeySequence(QKeySequence(str)));
×
1097
        }
1098
        else if (root.name() == KXMLQLCVCFrameNext)
8✔
1099
        {
1100
            QString str = loadXMLSources(root, nextPageInputSourceId);
×
1101
            if (str.isEmpty() == false)
×
1102
                setNextPageKeySequence(stripKeySequence(QKeySequence(str)));
×
1103
        }
1104
        else if (root.name() == KXMLQLCVCFramePrevious)
8✔
1105
        {
1106
            QString str = loadXMLSources(root, previousPageInputSourceId);
×
1107
            if (str.isEmpty() == false)
×
1108
                setPreviousPageKeySequence(stripKeySequence(QKeySequence(str)));
×
1109
        }
1110
        else if (root.name() == KXMLQLCVCFramePagesLoop)
8✔
1111
        {
1112
            if (root.readElementText() == KXMLQLCTrue)
×
1113
                setPagesLoop(true);
×
1114
            else
1115
                setPagesLoop(false);
×
1116
        }
1117
        else if (root.name() == KXMLQLCVCFramePageShortcut)
8✔
1118
        {
1119
            VCFramePageShortcut *shortcut = new VCFramePageShortcut(0xFF, 0xFF);
×
1120
            if (shortcut->loadXML(root))
×
1121
            {
1122
                shortcut->m_id = VCFrame::shortcutsBaseInputSourceId + shortcut->m_page;
×
1123
                newShortcuts.append(shortcut);
×
1124
            }
1125
        }
1126
        else if (root.name() == KXMLQLCVCFrame)
8✔
1127
        {
1128
            /* Create a new frame into its parent */
1129
            VCFrame* frame = new VCFrame(this, m_doc, true);
1✔
1130
            if (frame->loadXML(root) == false)
1✔
1131
                delete frame;
×
1132
            else
1133
            {
1134
                addWidgetToPageMap(frame);
1✔
1135
                frame->show();
1✔
1136
            }
1137
        }
1138
        else if (root.name() == KXMLQLCVCLabel)
7✔
1139
        {
1140
            /* Create a new label into its parent */
1141
            VCLabel* label = new VCLabel(this, m_doc);
1✔
1142
            if (label->loadXML(root) == false)
1✔
1143
                delete label;
×
1144
            else
1145
            {
1146
                addWidgetToPageMap(label);
1✔
1147
                label->show();
1✔
1148
            }
1149
        }
1150
        else if (root.name() == KXMLQLCVCButton)
6✔
1151
        {
1152
            /* Create a new button into its parent */
1153
            VCButton* button = new VCButton(this, m_doc);
1✔
1154
            if (button->loadXML(root) == false)
1✔
1155
                delete button;
×
1156
            else
1157
            {
1158
                addWidgetToPageMap(button);
1✔
1159
                button->show();
1✔
1160
            }
1161
        }
1162
        else if (root.name() == KXMLQLCVCXYPad)
5✔
1163
        {
1164
            /* Create a new xy pad into its parent */
1165
            VCXYPad* xypad = new VCXYPad(this, m_doc);
1✔
1166
            if (xypad->loadXML(root) == false)
1✔
1167
                delete xypad;
×
1168
            else
1169
            {
1170
                addWidgetToPageMap(xypad);
1✔
1171
                xypad->show();
1✔
1172
            }
1173
        }
1174
        else if (root.name() == KXMLQLCVCSlider)
4✔
1175
        {
1176
            /* Create a new slider into its parent */
1177
            VCSlider* slider = new VCSlider(this, m_doc);
1✔
1178
            if (slider->loadXML(root) == false)
1✔
1179
            {
1180
                delete slider;
×
1181
            }
1182
            else
1183
            {
1184
                addWidgetToPageMap(slider);
1✔
1185
                slider->show();
1✔
1186
                // always connect a slider as if it was a submaster
1187
                // cause this signal is emitted only when a slider is
1188
                // a submaster
1189
                connect(slider, SIGNAL(submasterValueChanged(qreal)),
1✔
1190
                        this, SLOT(slotSubmasterValueChanged(qreal)));
1191
            }
1192
        }
1193
        else if (root.name() == KXMLQLCVCSoloFrame)
3✔
1194
        {
1195
            /* Create a new frame into its parent */
1196
            VCSoloFrame* soloframe = new VCSoloFrame(this, m_doc, true);
1✔
1197
            if (soloframe->loadXML(root) == false)
1✔
1198
                delete soloframe;
×
1199
            else
1200
            {
1201
                if (m_doc->mode() == Doc::Operate)
1✔
1202
                    soloframe->updateChildrenConnection(true);
×
1203
                addWidgetToPageMap(soloframe);
1✔
1204
                soloframe->show();
1✔
1205
            }
1206
        }
1207
        else if (root.name() == KXMLQLCVCCueList)
2✔
1208
        {
1209
            /* Create a new cuelist into its parent */
1210
            VCCueList* cuelist = new VCCueList(this, m_doc);
1✔
1211
            if (cuelist->loadXML(root) == false)
1✔
1212
                delete cuelist;
×
1213
            else
1214
            {
1215
                addWidgetToPageMap(cuelist);
1✔
1216
                cuelist->show();
1✔
1217
            }
1218
        }
1219
        else if (root.name() == KXMLQLCVCSpeedDial)
1✔
1220
        {
1221
            /* Create a new speed dial into its parent */
1222
            VCSpeedDial* dial = new VCSpeedDial(this, m_doc);
×
1223
            if (dial->loadXML(root) == false)
×
1224
                delete dial;
×
1225
            else
1226
            {
1227
                addWidgetToPageMap(dial);
×
1228
                dial->show();
×
1229
            }
1230
        }
1231
        else if (root.name() == KXMLQLCVCAudioTriggers)
1✔
1232
        {
1233
            VCAudioTriggers* triggers = new VCAudioTriggers(this, m_doc);
×
1234
            if (triggers->loadXML(root) == false)
×
1235
                delete triggers;
×
1236
            else
1237
            {
1238
                addWidgetToPageMap(triggers);
×
1239
                triggers->show();
×
1240
            }
1241
        }
1242
        else if (root.name() == KXMLQLCVCClock)
1✔
1243
        {
1244
            /* Create a new VCClock into its parent */
1245
            VCClock* clock = new VCClock(this, m_doc);
×
1246
            if (clock->loadXML(root) == false)
×
1247
                delete clock;
×
1248
            else
1249
            {
1250
                addWidgetToPageMap(clock);
×
1251
                clock->show();
×
1252
            }
1253
        }
1254
        else if (root.name() == KXMLQLCVCMatrix)
1✔
1255
        {
1256
            /* Create a new VCMatrix into its parent */
1257
            VCMatrix* matrix = new VCMatrix(this, m_doc);
×
1258
            if (matrix->loadXML(root) == false)
×
1259
                delete matrix;
×
1260
            else
1261
            {
1262
                addWidgetToPageMap(matrix);
×
1263
                matrix->show();
×
1264
            }
1265
        }
1266
        else
1267
        {
1268
            qWarning() << Q_FUNC_INFO << "Unknown frame tag:" << root.name().toString();
1✔
1269
            root.skipCurrentElement();
1✔
1270
        }
1271
    }
1272

1273
    if (multipageMode() == true)
3✔
1274
    {
1275
        if (newShortcuts.count() == m_totalPagesNumber)
×
1276
            setShortcuts(newShortcuts);
×
1277
        else
1278
            qWarning() << Q_FUNC_INFO << "Shortcut number does not match page number";
×
1279

1280
        // Set page again to update header
1281
        slotSetPage(m_currentPage);
×
1282
    }
1283

1284
    if (disableState == true)
3✔
1285
        setDisableState(true);
×
1286

1287
    return true;
3✔
1288
}
1289

1290
bool VCFrame::saveXML(QXmlStreamWriter *doc)
3✔
1291
{
1292
    Q_ASSERT(doc != NULL);
3✔
1293

1294
    /* VC Frame entry */
1295
    doc->writeStartElement(xmlTagName());
3✔
1296

1297
    saveXMLCommon(doc);
3✔
1298

1299
    /* Save appearance */
1300
    saveXMLAppearance(doc);
3✔
1301

1302
    if (isBottomFrame() == false)
3✔
1303
    {
1304
        /* Save widget proportions only for child frames */
1305
        if (isCollapsed())
2✔
1306
        {
1307
            resize(QSize(m_width, m_height));
×
1308
            saveXMLWindowState(doc);
×
1309
            resize(QSize(200, 40));
×
1310
        }
1311
        else
1312
            saveXMLWindowState(doc);
2✔
1313

1314
        /* Allow children */
1315
        doc->writeTextElement(KXMLQLCVCFrameAllowChildren, allowChildren() ? KXMLQLCTrue : KXMLQLCFalse);
2✔
1316

1317
        /* Allow resize */
1318
        doc->writeTextElement(KXMLQLCVCFrameAllowResize, allowResize() ? KXMLQLCTrue : KXMLQLCFalse);
2✔
1319

1320
        /* ShowHeader */
1321
        doc->writeTextElement(KXMLQLCVCFrameShowHeader, isHeaderVisible() ? KXMLQLCTrue : KXMLQLCFalse);
2✔
1322

1323
        /* ShowEnableButton */
1324
        doc->writeTextElement(KXMLQLCVCFrameShowEnableButton, isEnableButtonVisible() ? KXMLQLCTrue : KXMLQLCFalse);
2✔
1325

1326
        /* Solo frame mixing */
1327
        if (this->type() == SoloFrameWidget)
2✔
1328
        {
1329
            if (reinterpret_cast<VCSoloFrame*>(this)->soloframeMixing())
×
1330
                doc->writeTextElement(KXMLQLCVCSoloFrameMixing, KXMLQLCTrue);
×
1331
            else
1332
                doc->writeTextElement(KXMLQLCVCSoloFrameMixing, KXMLQLCFalse);
×
1333
        }
1334

1335
        /* Collapsed */
1336
        doc->writeTextElement(KXMLQLCVCFrameIsCollapsed, isCollapsed() ? KXMLQLCTrue : KXMLQLCFalse);
2✔
1337

1338
        /* Disabled */
1339
        doc->writeTextElement(KXMLQLCVCFrameIsDisabled, isDisabled() ? KXMLQLCTrue : KXMLQLCFalse);
2✔
1340

1341
        /* Enable control */
1342
        QString keySeq = m_enableKeySequence.toString();
4✔
1343
        QSharedPointer<QLCInputSource> enableSrc = inputSource(enableInputSourceId);
4✔
1344

1345
        if (keySeq.isEmpty() == false || (!enableSrc.isNull() && enableSrc->isValid()))
2✔
1346
        {
1347
            doc->writeStartElement(KXMLQLCVCFrameEnableSource);
×
1348
            if (keySeq.isEmpty() == false)
×
1349
                doc->writeTextElement(KXMLQLCVCWidgetKey, keySeq);
×
1350
            saveXMLInput(doc, enableSrc);
×
1351
            doc->writeEndElement();
×
1352
        }
1353

1354
        /* Multipage mode */
1355
        if (multipageMode() == true)
2✔
1356
        {
1357
            doc->writeStartElement(KXMLQLCVCFrameMultipage);
×
1358
            doc->writeAttribute(KXMLQLCVCFramePagesNumber, QString::number(totalPagesNumber()));
×
1359
            doc->writeAttribute(KXMLQLCVCFrameCurrentPage, QString::number(currentPage()));
×
1360
            doc->writeEndElement();
×
1361

1362
            /* Next page */
1363
            keySeq = m_nextPageKeySequence.toString();
×
1364
            QSharedPointer<QLCInputSource> nextSrc = inputSource(nextPageInputSourceId);
×
1365

1366
            if (keySeq.isEmpty() == false || (!nextSrc.isNull() && nextSrc->isValid()))
×
1367
            {
1368
                doc->writeStartElement(KXMLQLCVCFrameNext);
×
1369
                if (keySeq.isEmpty() == false)
×
1370
                    doc->writeTextElement(KXMLQLCVCWidgetKey, keySeq);
×
1371
                saveXMLInput(doc, nextSrc);
×
1372
                doc->writeEndElement();
×
1373
            }
1374

1375
            /* Previous page */
1376
            keySeq = m_previousPageKeySequence.toString();
×
1377
            QSharedPointer<QLCInputSource> prevSrc = inputSource(previousPageInputSourceId);
×
1378

1379
            if (keySeq.isEmpty() == false || (!prevSrc.isNull() && prevSrc->isValid()))
×
1380
            {
1381
                doc->writeStartElement(KXMLQLCVCFramePrevious);
×
1382
                if (keySeq.isEmpty() == false)
×
1383
                    doc->writeTextElement(KXMLQLCVCWidgetKey, keySeq);
×
1384
                saveXMLInput(doc, prevSrc);
×
1385
                doc->writeEndElement();
×
1386
            }
1387

1388
            /* Page shortcuts */
1389
            foreach (VCFramePageShortcut *shortcut, shortcuts())
×
1390
                shortcut->saveXML(doc);
×
1391

1392
            /* Pages Loop */
1393
            doc->writeTextElement(KXMLQLCVCFramePagesLoop, m_pagesLoop ? KXMLQLCTrue : KXMLQLCFalse);
×
1394
        }
1395
    }
1396

1397
    /* Save children */
1398
    QListIterator <VCWidget*> it(findChildren<VCWidget*>());
6✔
1399
    while (it.hasNext() == true)
6✔
1400
    {
1401
        VCWidget* widget = it.next();
3✔
1402

1403
        /* findChildren() is recursive, so the list contains all
1404
           possible child widgets below this frame. Each frame must
1405
           save only its direct children to preserve hierarchy, so
1406
           save only such widgets that have this widget as their
1407
           direct parent. */
1408
        if (widget->parentWidget() == this)
3✔
1409
            widget->saveXML(doc);
2✔
1410
    }
1411

1412
    /* End the <Frame> tag */
1413
    doc->writeEndElement();
3✔
1414

1415
    return true;
6✔
1416
}
1417

1418
void VCFrame::postLoad()
3✔
1419
{
1420
    QListIterator <VCWidget*> it(findChildren<VCWidget*>());
9✔
1421
    while (it.hasNext() == true)
10✔
1422
    {
1423
        VCWidget* widget = it.next();
7✔
1424

1425
        /* findChildren() is recursive, so the list contains all
1426
           possible child widgets below this frame. Each frame must
1427
           save only its direct children to preserve hierarchy, so
1428
           save only such widgets that have this widget as their
1429
           direct parent. */
1430
        if (widget->parentWidget() == this)
7✔
1431
            widget->postLoad();
7✔
1432
    }
1433
}
3✔
1434

1435
QString VCFrame::xmlTagName() const
6✔
1436
{
1437
    return KXMLQLCVCFrame;
6✔
1438
}
1439

1440
/*****************************************************************************
1441
 * Custom menu
1442
 *****************************************************************************/
1443

1444
QMenu* VCFrame::customMenu(QMenu* parentMenu)
8✔
1445
{
1446
    QMenu* menu = NULL;
8✔
1447
    VirtualConsole* vc = VirtualConsole::instance();
8✔
1448

1449
    if (allowChildren() == true && vc != NULL)
8✔
1450
    {
1451
        /* Basically, just returning VC::addMenu() would suffice here, but
1452
           since the returned menu will be deleted when the current widget
1453
           changes, we have to copy the menu's contents into a new menu. */
1454
        menu = new QMenu(parentMenu);
8✔
1455
        menu->setTitle(tr("Add"));
8✔
1456
        QListIterator <QAction*> it(vc->addMenu()->actions());
24✔
1457
        while (it.hasNext() == true)
144✔
1458
            menu->addAction(it.next());
136✔
1459
    }
1460

1461
    return menu;
8✔
1462
}
1463

1464
/*****************************************************************************
1465
 * Event handlers
1466
 *****************************************************************************/
1467

1468
void VCFrame::handleWidgetSelection(QMouseEvent* e)
4✔
1469
{
1470
    /* No point coming here if there is no VC */
1471
    VirtualConsole* vc = VirtualConsole::instance();
4✔
1472
    if (vc == NULL)
4✔
1473
        return;
×
1474

1475
    /* Don't allow selection of the bottom frame. Selecting it will always
1476
       actually clear the current selection. */
1477
    if (isBottomFrame() == false)
4✔
1478
        VCWidget::handleWidgetSelection(e);
1✔
1479
    else
1480
        vc->clearWidgetSelection();
3✔
1481
}
1482

1483
void VCFrame::mouseMoveEvent(QMouseEvent* e)
2✔
1484
{
1485
    if (isBottomFrame() == false)
2✔
1486
        VCWidget::mouseMoveEvent(e);
1✔
1487
    else
1488
        QWidget::mouseMoveEvent(e);
1✔
1489

1490
    if (isCollapsed() == false)
2✔
1491
    {
1492
        m_width = this->width();
2✔
1493
        m_height = this->height();
2✔
1494
    }
1495
}
2✔
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