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

mcallegari / qlcplus / 8961243534

05 May 2024 09:23PM UTC coverage: 32.068% (+4.0%) from 28.094%
8961243534

push

github

mcallegari
Merge branch 'master' into qmltoqt6

902 of 2557 new or added lines in 140 files covered. (35.28%)

166 existing lines in 76 files now uncovered.

15395 of 48008 relevant lines covered (32.07%)

22949.67 hits per line

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

44.91
/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
    {
UNCOV
120
        widget->setDisableState(disable);
×
NEW
121
        if (!disable)
×
NEW
122
            widget->adjustIntensity(intensity());
×
123
    }
124

125
    m_disableState = disable;
×
126

NEW
127
    emit disableStateChanged(disable);
×
128
    updateFeedback();
×
129
}
×
130

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

136
    m_liveEdit = liveEdit;
×
137

138
    if (!m_disableState)
×
139
        enableWidgetUI(!m_liveEdit);
×
140

141
    updateSubmasterValue();
×
142

143
    unsetCursor();
×
144
    update();
×
145
}
146

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

169
    VCWidget::setCaption(text);
5✔
170
}
5✔
171

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

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

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

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

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

213
    if (m_hbox == NULL)
2✔
214
        createHeader();
1✔
215

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

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

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

241
    m_showEnableButton = show;
2✔
242
}
2✔
243

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

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

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

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

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

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

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

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

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

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

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

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

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

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

358
/*********************************************************************
359
 * Pages
360
 *********************************************************************/
361

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

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

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

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

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

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

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

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

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

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

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

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

459
    m_multiPageMode = enable;
×
460
}
461

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

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

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

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

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

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

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

516
/*********************************************************************
517
 * Shortcuts
518
 *********************************************************************/
519

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

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

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

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

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

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

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

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

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

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

591
    sendFeedback(m_currentPage, nextPageInputSourceId);
×
592
}
×
593

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

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

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

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

640
    VCWidget::slotModeChanged(mode);
21✔
641
}
21✔
642

643
/*********************************************************************
644
 * Submasters
645
 *********************************************************************/
646

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

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

675
void VCFrame::adjustIntensity(qreal val)
×
676
{
NEW
677
    VCWidget::adjustIntensity(val);
×
678

NEW
679
    if (isDisabled())
×
NEW
680
        return;
×
681

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

691
/*****************************************************************************
692
 * Key Sequences
693
 *****************************************************************************/
694

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

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

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

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

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

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

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

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

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

765
    foreach (VCFramePageShortcut* shortcut, m_pageShortcuts)
17✔
766
    {
767
        QSharedPointer<QLCInputSource> src = shortcut->m_inputSource;
×
768
        if (!src.isNull() && src->isValid() == true)
×
769
        {
770
            if (m_currentPage == shortcut->m_page)
×
NEW
771
                sendFeedback(src->feedbackValue(QLCInputFeedback::UpperValue), src);
×
772
            else
NEW
773
                sendFeedback(src->feedbackValue(QLCInputFeedback::LowerValue), src);
×
774
        }
775
    }
776

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

786
/*****************************************************************************
787
 * External input
788
 *****************************************************************************/
789

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

795
    quint32 pagedCh = (page() << 16) | channel;
×
796

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

817
/*****************************************************************************
818
 * Clipboard
819
 *****************************************************************************/
820

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

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

832
    return frame;
1✔
833
}
834

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

841
    setHeaderVisible(frame->m_showHeader);
1✔
842
    setEnableButtonVisible(frame->m_showEnableButton);
1✔
843

844
    setMultipageMode(frame->m_multiPageMode);
1✔
845
    setTotalPagesNumber(frame->m_totalPagesNumber);
1✔
846

847
    setPagesLoop(frame->m_pagesLoop);
1✔
848

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

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

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

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

873
        if (childCopy != NULL)
1✔
874
        {
875
            addWidgetToPageMap(childCopy);
1✔
876

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

889
    if (m_multiPageMode)
1✔
890
        slotSetPage(frame->m_currentPage);
×
891

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

896
/*****************************************************************************
897
 * Properties
898
 *****************************************************************************/
899

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

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

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

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

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

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

990
/*****************************************************************************
991
 * Load & Save
992
 *****************************************************************************/
993

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

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

1004
    /* Widget commons */
1005
    loadXMLCommon(root);
3✔
1006

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

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

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

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

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

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

1286
    if (disableState == true)
3✔
1287
        setDisableState(true);
×
1288

1289
    return true;
3✔
1290
}
1291

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

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

1299
    saveXMLCommon(doc);
3✔
1300

1301
    /* Save appearance */
1302
    saveXMLAppearance(doc);
3✔
1303

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

1417
    return true;
6✔
1418
}
1419

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

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

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

1442
/*****************************************************************************
1443
 * Custom menu
1444
 *****************************************************************************/
1445

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

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

1463
    return menu;
8✔
1464
}
1465

1466
/*****************************************************************************
1467
 * Event handlers
1468
 *****************************************************************************/
1469

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

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

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

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