• 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

74.88
/ui/src/virtualconsole/vcwidget.cpp
1
/*
2
  Q Light Controller Plus
3
  vcwidget.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 <QStyleOptionFrame>
22
#include <QXmlStreamReader>
23
#include <QXmlStreamWriter>
24
#include <QApplication>
25
#include <QInputDialog>
26
#include <QColorDialog>
27
#include <QFileDialog>
28
#include <QFontDialog>
29
#include <QMessageBox>
30
#include <QMouseEvent>
31
#include <QMetaObject>
32
#include <QPainter>
33
#include <QPalette>
34
#include <QCursor>
35
#include <QPixmap>
36
#include <QDebug>
37
#include <QBrush>
38
#include <QPoint>
39
#include <QStyle>
40
#include <QSize>
41
#include <QMenu>
42
#include <QList>
43
#include <cmath>
44

45
#include "qlcinputsource.h"
46
#include "qlcfile.h"
47

48
#include "qlcinputchannel.h"
49
#include "virtualconsole.h"
50
#include "inputpatch.h"
51
#include "vcwidget.h"
52
#include "doc.h"
53

54
#define GRID_RESOLUTION 5
55

56
VCWidget::VCWidget(QWidget* parent, Doc* doc)
177✔
57
    : QWidget(parent)
58
    , m_doc(doc)
59
    , m_id(invalidId())
354✔
60
    , m_disableState(false)
61
    , m_page(0)
62
    , m_allowChildren(false)
63
    , m_allowResize(true)
64
    , m_intensityOverrideId(Function::invalidAttributeId())
354✔
65
    , m_intensity(1.0)
66
    , m_liveEdit(VirtualConsole::instance()->liveEdit())
177✔
67
{
68
    Q_ASSERT(parent != NULL);
177✔
69
    Q_ASSERT(doc != NULL);
177✔
70

71
    /* Set the class name "VCWidget" as the object name as well */
72
    setObjectName(VCWidget::staticMetaObject.className());
177✔
73

74
    setMinimumSize(QSize(20, 20));
177✔
75

76
    m_type = UnknownWidget;
177✔
77
    m_hasCustomBackgroundColor = false;
177✔
78
    m_hasCustomForegroundColor = false;
177✔
79
    m_backgroundImage = QString();
177✔
80
    m_hasCustomFont = false;
177✔
81
    m_frameStyle = KVCFrameStyleNone;
177✔
82

83
    m_resizeMode = false;
177✔
84

85
    setBackgroundRole(QPalette::Window);
177✔
86
    setAutoFillBackground(true);
177✔
87
    setEnabled(true);
177✔
88

89
    connect(m_doc, SIGNAL(modeChanged(Doc::Mode)),
177✔
90
            this, SLOT(slotModeChanged(Doc::Mode)));
91

92
    /* Listen to the virtual console key signals */
93
    connect(VirtualConsole::instance(), SIGNAL(keyPressed(const QKeySequence&)),
177✔
94
            this, SLOT(slotKeyPressed(const QKeySequence&)));
95
    connect(VirtualConsole::instance(), SIGNAL(keyReleased(const QKeySequence&)),
177✔
96
            this, SLOT(slotKeyReleased(const QKeySequence&)));
97
}
177✔
98

99
VCWidget::~VCWidget()
177✔
100
{
101
}
177✔
102

103
/*****************************************************************************
104
 * ID
105
 *****************************************************************************/
106

107
void VCWidget::setID(quint32 id)
1✔
108
{
109
    /* Don't set doc modified status or emit changed signal, because this
110
       function is called only once during widget creation. */
111
    m_id = id;
1✔
112
}
1✔
113

114
quint32 VCWidget::id() const
18✔
115
{
116
    return m_id;
18✔
117
}
118

119
quint32 VCWidget::invalidId()
186✔
120
{
121
    return UINT_MAX;
186✔
122
}
123

124
/*********************************************************************
125
 * Type
126
 *********************************************************************/
127

128
void VCWidget::setType(int type)
153✔
129
{
130
    m_type = type;
153✔
131
}
153✔
132

133
int VCWidget::type()
5✔
134
{
135
    return m_type;
5✔
136
}
137

138
QString VCWidget::typeToString(int type)
×
139
{
140
    switch (type)
×
141
    {
142

143
        case ButtonWidget: return QString(tr("Button"));
×
144
        case SliderWidget: return QString(tr("Slider"));
×
145
        case XYPadWidget: return QString(tr("XYPad"));
×
146
        case FrameWidget: return QString(tr("Frame"));
×
147
        case SoloFrameWidget: return QString(tr("Solo frame"));
×
148
        case SpeedDialWidget: return QString(tr("Speed dial"));
×
149
        case CueListWidget: return QString(tr("Cue list"));
×
150
        case LabelWidget: return QString(tr("Label"));
×
151
        case AudioTriggersWidget: return QString(tr("Audio Triggers"));
×
152
        case AnimationWidget: return QString(tr("Animation"));
×
153
        case ClockWidget: return QString(tr("Clock"));
×
154
        case UnknownWidget:
×
155
        default:
156
             return QString(tr("Unknown"));
×
157
    }
158
    return QString(tr("Unknown"));
159
}
160

161
QIcon VCWidget::typeToIcon(int type)
×
162
{
163
    switch (type)
×
164
    {
165
        case ButtonWidget: return QIcon(":/button.png");
×
166
        case SliderWidget: return QIcon(":/slider.png");
×
167
        case XYPadWidget: return QIcon(":/xypad.png");
×
168
        case FrameWidget: return QIcon(":/frame.png");
×
169
        case SoloFrameWidget: return QIcon(":/soloframe.png");
×
170
        case SpeedDialWidget: return QIcon(":/speed.png");
×
171
        case CueListWidget: return QIcon(":/cuelist.png");
×
172
        case LabelWidget: return QIcon(":/label.png");
×
173
        case AudioTriggersWidget: return QIcon(":/audioinput.png");
×
174
        case AnimationWidget: return QIcon(":/rgbmatrix.png");
×
175
        case ClockWidget: return QIcon(":/clock.png");
×
176
        case UnknownWidget:
×
177
        default:
178
             return QIcon(":/virtualconsole.png");
×
179
    }
180
    return QIcon(":/virtualconsole.png");
181
}
182

183
/*********************************************************************
184
 * Disable state
185
 *********************************************************************/
186

187
void VCWidget::setDisableState(bool disable)
×
188
{
189
    m_disableState = disable;
×
190
    if (mode() == Doc::Operate)
×
191
    {
192
        setEnabled(!disable);
×
193
        enableWidgetUI(!disable);
×
194
    }
195
}
×
196

197
void VCWidget::enableWidgetUI(bool enable)
×
198
{
199
    Q_UNUSED(enable)
200
}
×
201

202
bool VCWidget::isDisabled()
76✔
203
{
204
    return m_disableState;
76✔
205
}
206

207
/*********************************************************************
208
 * Page
209
 *********************************************************************/
210

211
void VCWidget::setPage(int pNum)
×
212
{
213
    m_page = pNum;
×
214
}
×
215

216
int VCWidget::page()
46✔
217
{
218
    return m_page;
46✔
219
}
220

221
/*****************************************************************************
222
 * Clipboard
223
 *****************************************************************************/
224

225
bool VCWidget::copyFrom(const VCWidget* widget)
9✔
226
{
227
    if (widget == NULL)
9✔
228
        return false;
1✔
229

230
    setBackgroundImage(widget->m_backgroundImage);
8✔
231

232
    m_hasCustomBackgroundColor = widget->m_hasCustomBackgroundColor;
8✔
233
    if (m_hasCustomBackgroundColor == true)
8✔
234
        setBackgroundColor(widget->backgroundColor());
1✔
235

236
    m_hasCustomForegroundColor = widget->m_hasCustomForegroundColor;
8✔
237
    if (m_hasCustomForegroundColor == true)
8✔
238
        setForegroundColor(widget->foregroundColor());
1✔
239

240
    m_hasCustomFont = widget->m_hasCustomFont;
8✔
241
    if (m_hasCustomFont == true)
8✔
242
        setFont(widget->font());
1✔
243

244
    m_frameStyle = widget->m_frameStyle;
8✔
245

246
    setGeometry(widget->geometry());
8✔
247
    setCaption(widget->caption());
8✔
248

249
    m_allowChildren = widget->m_allowChildren;
8✔
250
    m_allowResize = widget->m_allowResize;
8✔
251

252
    QHashIterator <quint8, QSharedPointer<QLCInputSource> > it(widget->m_inputs);
8✔
253
    while (it.hasNext() == true)
11✔
254
    {
255
        it.next();
3✔
256
        quint8 id = it.key();
3✔
257
        QSharedPointer<QLCInputSource> src(new QLCInputSource(it.value()->universe(), it.value()->channel()));
6✔
258
        src->setRange(it.value()->lowerValue(), it.value()->upperValue());
3✔
259
        setInputSource(src, id);
3✔
260
    }
261

262
    m_page = widget->m_page;
8✔
263

264
    return true;
8✔
265
}
266

267
/*****************************************************************************
268
 * Background image
269
 *****************************************************************************/
270

271
void VCWidget::setBackgroundImage(const QString& path)
14✔
272
{
273
    QPalette pal = palette();
28✔
274

275
    m_hasCustomBackgroundColor = false;
14✔
276
    m_backgroundImage = path;
14✔
277

278
    pal.setBrush(QPalette::Window, QBrush(QPixmap(path)));
14✔
279
    setPalette(pal);
14✔
280

281
    m_doc->setModified();
14✔
282
}
14✔
283

284
QString VCWidget::backgroundImage() const
24✔
285
{
286
    return m_backgroundImage;
24✔
287
}
288

289

290
/*****************************************************************************
291
 * Background color
292
 *****************************************************************************/
293

294
void VCWidget::setBackgroundColor(const QColor& color)
11✔
295
{
296
    QPalette pal = palette();
22✔
297

298
    m_hasCustomBackgroundColor = true;
11✔
299
    m_backgroundImage = QString();
11✔
300

301
    pal.setColor(QPalette::Window, color);
11✔
302
    setPalette(pal);
11✔
303

304
    m_doc->setModified();
11✔
305
}
11✔
306

307
QColor VCWidget::backgroundColor() const
11✔
308
{
309
    return palette().color(QPalette::Window);
11✔
310
}
311

312
bool VCWidget::hasCustomBackgroundColor() const
29✔
313
{
314
    return m_hasCustomBackgroundColor;
29✔
315
}
316

317
void VCWidget::resetBackgroundColor()
3✔
318
{
319
    QColor fg;
3✔
320

321
    m_hasCustomBackgroundColor = false;
3✔
322
    m_backgroundImage = QString();
3✔
323

324
    /* Store foreground color */
325
    if (m_hasCustomForegroundColor == true)
3✔
326
        fg = palette().color(QPalette::WindowText);
2✔
327

328
    /* Reset the whole palette to application palette */
329
    setPalette(QApplication::palette());
3✔
330
    /* setAutoFillBackground(false); */
331

332
    /* Restore foreground color */
333
    if (fg.isValid() == true)
3✔
334
    {
335
        QPalette pal = palette();
4✔
336
        pal.setColor(QPalette::WindowText, fg);
2✔
337
        setPalette(pal);
2✔
338
    }
339

340
    m_doc->setModified();
3✔
341
}
3✔
342

343
/*****************************************************************************
344
 * Foreground color
345
 *****************************************************************************/
346

347
void VCWidget::setForegroundColor(const QColor& color)
7✔
348
{
349
    QPalette pal = palette();
14✔
350

351
    m_hasCustomForegroundColor = true;
7✔
352

353
    pal.setColor(QPalette::WindowText, color);
7✔
354
    setPalette(pal);
7✔
355

356
    m_doc->setModified();
7✔
357
}
7✔
358

359
QColor VCWidget::foregroundColor() const
10✔
360
{
361
    return palette().color(QPalette::WindowText);
10✔
362
}
363

364
bool VCWidget::hasCustomForegroundColor() const
21✔
365
{
366
    return m_hasCustomForegroundColor;
21✔
367
}
368

369
void VCWidget::resetForegroundColor()
4✔
370
{
371
    QColor bg;
4✔
372

373
    m_hasCustomForegroundColor = false;
4✔
374

375
    /* Store background color */
376
    if (hasCustomBackgroundColor() == true)
4✔
377
        bg = palette().color(QPalette::Window);
2✔
378

379
    /* Reset the whole palette to application palette */
380
    setPalette(QApplication::palette());
4✔
381

382
    /* Restore foreground color (the first two emit Doc::modified() signal) */
383
    if (bg.isValid() == true)
4✔
384
        setBackgroundColor(bg);
2✔
385
    else if (backgroundImage().isEmpty() == false)
2✔
386
        setBackgroundImage(backgroundImage());
1✔
387
    else
388
        m_doc->setModified();
1✔
389
}
4✔
390

391
/*****************************************************************************
392
 * Font
393
 *****************************************************************************/
394

395
void VCWidget::setFont(const QFont& font)
10✔
396
{
397
    m_hasCustomFont = true;
10✔
398
    QWidget::setFont(font);
10✔
399
    m_doc->setModified();
10✔
400
}
10✔
401

402
QFont VCWidget::font() const
25✔
403
{
404
    return QWidget::font();
25✔
405
}
406

407
bool VCWidget::hasCustomFont() const
12✔
408
{
409
    return m_hasCustomFont;
12✔
410
}
411

412
void VCWidget::resetFont()
1✔
413
{
414
    QWidget::setFont(QApplication::font());
1✔
415
    m_hasCustomFont = false;
1✔
416
    m_doc->setModified();
1✔
417
}
1✔
418

419
/*****************************************************************************
420
 * Caption
421
 *****************************************************************************/
422

423
void VCWidget::setCaption(const QString& text)
88✔
424
{
425
    setWindowTitle(text);
88✔
426
    update();
88✔
427
    m_doc->setModified();
88✔
428
}
88✔
429

430
QString VCWidget::caption() const
54✔
431
{
432
    return windowTitle();
54✔
433
}
434

435
/*****************************************************************************
436
 * Frame style
437
 *****************************************************************************/
438

439
void VCWidget::setFrameStyle(int style)
230✔
440
{
441
    m_frameStyle = style;
230✔
442
    update();
230✔
443
    m_doc->setModified();
230✔
444
}
230✔
445

446
int VCWidget::frameStyle() const
83✔
447
{
448
    return m_frameStyle;
83✔
449
}
450

451
void VCWidget::resetFrameStyle()
1✔
452
{
453
    setFrameStyle(KVCFrameStyleNone);
1✔
454
}
1✔
455

456
QString VCWidget::frameStyleToString(int style)
13✔
457
{
458
    if (style == KVCFrameStyleSunken)
13✔
459
        return "Sunken";
6✔
460
    else if (style == KVCFrameStyleRaised)
7✔
461
        return "Raised";
2✔
462
    else
463
        return "None";
5✔
464
}
465

466
int VCWidget::stringToFrameStyle(const QString& style)
6✔
467
{
468
    if (style == "Sunken")
6✔
469
        return KVCFrameStyleSunken;
3✔
470
    else if (style == "Raised")
3✔
471
        return KVCFrameStyleRaised;
1✔
472
    else
473
        return KVCFrameStyleNone;
2✔
474
}
475

476
/*****************************************************************************
477
 * Allow adding children
478
 *****************************************************************************/
479

480
void VCWidget::setAllowChildren(bool allow)
99✔
481
{
482
    m_allowChildren = allow;
99✔
483
}
99✔
484

485
bool VCWidget::allowChildren() const
17✔
486
{
487
    return m_allowChildren;
17✔
488
}
489

490
/*********************************************************************
491
 * Allow resizing
492
 *********************************************************************/
493

494
void VCWidget::setAllowResize(bool allow)
5✔
495
{
496
    m_allowResize = allow;
5✔
497
}
5✔
498

499
bool VCWidget::allowResize() const
8✔
500
{
501
    return m_allowResize;
8✔
502
}
503

504
/*****************************************************************************
505
 * Properties
506
 *****************************************************************************/
507

508
void VCWidget::editProperties()
×
509
{
510
    QMessageBox::information(this, staticMetaObject.className(),
×
511
                             tr("This widget has no properties"));
×
512
}
×
513

514
/*********************************************************************
515
 * Intensity
516
 *********************************************************************/
517

518
void VCWidget::adjustFunctionIntensity(Function *f, qreal value)
11✔
519
{
520
    if (f == NULL)
11✔
521
        return;
×
522

523
    //qDebug() << "adjustFunctionIntensity" << caption() << "value" << value;
524

525
    if (m_intensityOverrideId == Function::invalidAttributeId())
11✔
526
        m_intensityOverrideId = f->requestAttributeOverride(Function::Intensity, value);
11✔
527
    else
528
        f->adjustAttribute(value, m_intensityOverrideId);
×
529
}
530

531
void VCWidget::resetIntensityOverrideAttribute()
12✔
532
{
533
    m_intensityOverrideId = Function::invalidAttributeId();
12✔
534
}
12✔
535

536
void VCWidget::adjustIntensity(qreal val)
×
537
{
538
    m_intensity = val;
×
539
}
×
540

541
qreal VCWidget::intensity() const
31✔
542
{
543
    return m_intensity;
31✔
544
}
545

546
/*****************************************************************************
547
 * External input
548
 *****************************************************************************/
549

550
bool VCWidget::acceptsInput()
63✔
551
{
552
    if (mode() == Doc::Design || isEnabled() == false || isDisabled())
63✔
553
        return false;
7✔
554

555
    return true;
56✔
556
}
557

558
bool VCWidget::checkInputSource(quint32 universe, quint32 channel,
49✔
559
                                uchar value, QObject *sender, quint32 id)
560
{
561
    QSharedPointer<QLCInputSource> const& src = m_inputs.value(id);
98✔
562
    if (src.isNull())
49✔
563
        return false;
8✔
564

565
    if (src->isValid() && src->universe() == universe && src->channel() == channel)
41✔
566
    {
567
        // if the event has been fired by an external controller
568
        // and this channel is set to relative mode, inform the input source
569
        // and don't allow the event to pass through. A synthetic event
570
        // will be generated by the input source itself
571
        if (src != sender && src->needsUpdate())
22✔
572
        {
573
            src->updateInputValue(value);
×
574
            return false;
×
575
        }
576
        return true;
22✔
577
    }
578

579
    return false;
19✔
580
}
581

582
void VCWidget::setInputSource(QSharedPointer<QLCInputSource> const& source, quint8 id)
34✔
583
{
584
    // Connect when the first valid input source is set
585
    if (m_inputs.isEmpty() == true && !source.isNull() && source->isValid() == true)
34✔
586
    {
587
        connect(m_doc->inputOutputMap(), SIGNAL(inputValueChanged(quint32,quint32,uchar)),
12✔
588
                this, SLOT(slotInputValueChanged(quint32,quint32,uchar)));
589
        connect(m_doc->inputOutputMap(), SIGNAL(profileChanged(quint32,QString)),
12✔
590
                this, SLOT(slotInputProfileChanged(quint32,QString)));
591
    }
592

593
    // Clear previous source
594
    if (m_inputs.contains(id))
34✔
595
    {
596
        disconnect(m_inputs.value(id).data(), SIGNAL(inputValueChanged(quint32,quint32,uchar)),
3✔
597
                this, SLOT(slotInputValueChanged(quint32,quint32,uchar)));
598
        m_inputs.remove(id);
3✔
599
    }
600

601
    // Assign
602
    if (!source.isNull() && source->isValid() == true)
34✔
603
    {
604
        m_inputs.insert(id, source);
30✔
605
        // now check if the source is defined in the associated universe
606
        // profile and if it has specific settings
607
        InputPatch *ip = m_doc->inputOutputMap()->inputPatch(source->universe());
30✔
608
        if (ip != NULL)
30✔
609
        {
610
            if (ip->profile() != NULL)
×
611
            {
612
                // Do not care about the page since input profiles don't do either
613
                QLCInputChannel *ich = ip->profile()->channel(source->channel() & 0xFFFF);
×
614
                if (ich != NULL)
×
615
                {
616
                    if (ich->movementType() == QLCInputChannel::Relative)
×
617
                    {
618
                        source->setWorkingMode(QLCInputSource::Relative);
×
619
                        source->setSensitivity(ich->movementSensitivity());
×
620
                        connect(source.data(), SIGNAL(inputValueChanged(quint32,quint32,uchar)),
×
621
                                this, SLOT(slotInputValueChanged(quint32,quint32,uchar)));
622
                    }
623
                    else if (ich->type() == QLCInputChannel::Encoder)
×
624
                    {
625
                        source->setWorkingMode(QLCInputSource::Encoder);
×
626
                        source->setSensitivity(ich->movementSensitivity());
×
627
                        connect(source.data(), SIGNAL(inputValueChanged(quint32,quint32,uchar)),
×
628
                                this, SLOT(slotInputValueChanged(quint32,quint32,uchar)));
629
                    }
630
                    else if (ich->type() == QLCInputChannel::Button)
×
631
                    {
632
                        if (ich->sendExtraPress() == true)
×
633
                        {
634
                            source->setSendExtraPressRelease(true);
×
635
                            connect(source.data(), SIGNAL(inputValueChanged(quint32,quint32,uchar)),
×
636
                                    this, SLOT(slotInputValueChanged(quint32,quint32,uchar)));
637
                        }
638

639
                        // user custom feedbacks have precedence over input profile custom feedbacks
640
                        source->setRange((source->lowerValue() != 0) ? source->lowerValue() : ich->lowerValue(),
×
641
                                         (source->upperValue() != UCHAR_MAX) ? source->upperValue() : ich->upperValue());
×
642
                    }
643
                }
644
            }
645
        }
646
    }
647

648
    // Disconnect when there are no more input sources present
649
    if (m_inputs.isEmpty() == true)
34✔
650
    {
651
        disconnect(m_doc->inputOutputMap(), SIGNAL(inputValueChanged(quint32,quint32,uchar)),
4✔
652
                   this, SLOT(slotInputValueChanged(quint32,quint32,uchar)));
653
        disconnect(m_doc->inputOutputMap(), SIGNAL(profileChanged(quint32,QString)),
4✔
654
                   this, SLOT(slotInputProfileChanged(quint32,QString)));
655
    }
656
}
34✔
657

658
QSharedPointer<QLCInputSource> VCWidget::inputSource(quint8 id) const
432✔
659
{
660
    return m_inputs.value(id);
432✔
661
}
662

663
void VCWidget::remapInputSources(int pgNum)
×
664
{
NEW
665
    foreach (quint8 s, m_inputs.keys())
×
666
    {
667
        QSharedPointer<QLCInputSource> src(m_inputs.value(s));
×
668
        src->setPage(pgNum);
×
669
        setInputSource(src, s);
×
670
    }
671
}
×
672

673
void VCWidget::sendFeedback(int value, quint8 id)
70✔
674
{
675
    /* Send input feedback */
676
    QSharedPointer<QLCInputSource> src = inputSource(id);
70✔
677
    sendFeedback(value, src);
70✔
678
}
70✔
679

680
void VCWidget::sendFeedback(int value, QSharedPointer<QLCInputSource> src)
70✔
681
{
682
    if (src.isNull() || src->isValid() == false)
70✔
683
        return;
58✔
684

685
    // if in relative mode, send a "feedback" to this
686
    // input source so it can continue to emit values
687
    // from the right position
688
    if (src->needsUpdate())
15✔
689
        src->updateOuputValue(value);
×
690

691
    if (acceptsInput() == false)
15✔
692
        return;
3✔
693

694
    QString chName = QString();
24✔
695

696
    InputPatch* pat = m_doc->inputOutputMap()->inputPatch(src->universe());
12✔
697
    if (pat != NULL)
12✔
698
    {
699
        QLCInputProfile* profile = pat->profile();
×
700
        if (profile != NULL)
×
701
        {
702
            QLCInputChannel* ich = profile->channel(src->channel());
×
703
            if (ich != NULL)
×
704
                chName = ich->name();
×
705
        }
706
    }
707
    m_doc->inputOutputMap()->sendFeedBack(src->universe(), src->channel(), value, chName);
12✔
708
}
709

710
void VCWidget::slotInputValueChanged(quint32 universe, quint32 channel, uchar value)
1✔
711
{
712
    Q_UNUSED(universe);
713
    Q_UNUSED(channel);
714
    Q_UNUSED(value);
715
}
1✔
716

717
void VCWidget::slotInputProfileChanged(quint32 universe, const QString &profileName)
×
718
{
719
    qDebug() << "[VCWdget] input profile changed" << profileName;
×
720

721
    QLCInputProfile *profile = m_doc->inputOutputMap()->profile(profileName);
×
722

NEW
723
    foreach (QSharedPointer<QLCInputSource> const& source, m_inputs.values())
×
724
    {
725
        if (!source.isNull() && source->universe() == universe)
×
726
        {
727
            // if the profile has been unset, reset all the valid
728
            // input sources to work in absolute mode
729
            if (profile == NULL)
×
730
            {
731
                source->setWorkingMode(QLCInputSource::Absolute);
×
732
            }
733
            else
734
            {
735
                QLCInputChannel *ich = profile->channel(source->channel());
×
736
                if (ich != NULL)
×
737
                {
738
                    if (ich->movementType() == QLCInputChannel::Absolute)
×
739
                        source->setWorkingMode(QLCInputSource::Absolute);
×
740
                    else
741
                    {
742
                        source->setWorkingMode(QLCInputSource::Relative);
×
743
                        source->setSensitivity(ich->movementSensitivity());
×
744
                    }
745
                }
746
            }
747
        }
748
    }
749
}
×
750

751
/*****************************************************************************
752
 * Key sequence handler
753
 *****************************************************************************/
754

755
QKeySequence VCWidget::stripKeySequence(const QKeySequence& seq)
12✔
756
{
757
    /* In QLC 3.2.x it is possible to set shortcuts like CTRL+X, but since
758
       CTRL is now the tap modifier, it must be stripped away. */
759
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
760
    int keys[4] = { 0, 0, 0, 0 };
12✔
761
    for (int i = 0; i < (int)seq.count() && i < 4; i++)
24✔
762
    {
763
        if ((seq[i] & Qt::ControlModifier) != 0)
12✔
764
            keys[i] = seq[i] & (~Qt::ControlModifier);
3✔
765
        else
766
            keys[i] = seq[i];
9✔
767
    }
768
#else
769
    QKeyCombination keys[4] = { Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown, Qt::Key_unknown};
770
    for (int i = 0; i < (int)seq.count() && i < 4; i++)
771
    {
772
        if ((seq[i].toCombined() & Qt::ControlModifier) != 0)
773
            keys[i].fromCombined(seq[i].toCombined() & (~Qt::ControlModifier));
774
        else
775
            keys[i] = seq[i];
776
    }
777
#endif
778
    return QKeySequence(keys[0], keys[1], keys[2], keys[3]);
24✔
779
}
780

781
void VCWidget::slotKeyPressed(const QKeySequence& keySequence)
1✔
782
{
783
    emit keyPressed(keySequence);
1✔
784
}
1✔
785

786
void VCWidget::slotKeyReleased(const QKeySequence& keySequence)
1✔
787
{
788
    emit keyReleased(keySequence);
1✔
789
}
1✔
790

791
/*****************************************************************************
792
 * Load & Save
793
 *****************************************************************************/
794

795
void VCWidget::postLoad()
6✔
796
{
797
    /* NOP */
798
}
6✔
799

800
bool VCWidget::loadXMLCommon(QXmlStreamReader &root)
14✔
801
{
802
    if (root.device() == NULL || root.hasError())
14✔
803
        return false;
×
804

805
    QXmlStreamAttributes attrs = root.attributes();
14✔
806

807
    /* ID */
808
    if (attrs.hasAttribute(KXMLQLCVCWidgetID))
14✔
809
        setID(attrs.value(KXMLQLCVCWidgetID).toString().toUInt());
×
810

811
    /* Caption */
812
    if (attrs.hasAttribute(KXMLQLCVCCaption))
14✔
813
        setCaption(attrs.value(KXMLQLCVCCaption).toString());
3✔
814

815
    /* Page */
816
    if (attrs.hasAttribute(KXMLQLCVCWidgetPage))
14✔
817
        setPage(attrs.value(KXMLQLCVCWidgetPage).toString().toInt());
×
818

819
    return true;
14✔
820
}
821

822
bool VCWidget::loadXMLAppearance(QXmlStreamReader &root)
9✔
823
{
824
    if (root.device() == NULL || root.hasError())
9✔
825
        return false;
×
826

827
    if (root.name() != KXMLQLCVCWidgetAppearance)
9✔
828
    {
829
        qWarning() << Q_FUNC_INFO << "Appearance node not found!";
1✔
830
        return false;
1✔
831
    }
832

833
    /* Children */
834
    while (root.readNextStartElement())
24✔
835
    {
836
        if (root.name() == KXMLQLCVCFrameStyle)
16✔
837
        {
838
            setFrameStyle(stringToFrameStyle(root.readElementText()));
2✔
839
        }
840
        else if (root.name() == KXMLQLCVCWidgetForegroundColor)
14✔
841
        {
842
            QString str = root.readElementText();
4✔
843
            if (str != KXMLQLCVCWidgetColorDefault)
2✔
844
                setForegroundColor(QColor(str.toUInt()));
1✔
845
            else if (hasCustomForegroundColor() == true)
1✔
846
                resetForegroundColor();
1✔
847
        }
848
        else if (root.name() == KXMLQLCVCWidgetBackgroundColor)
12✔
849
        {
850
            QString str = root.readElementText();
4✔
851
            if (str != KXMLQLCVCWidgetColorDefault)
2✔
852
                setBackgroundColor(QColor(str.toUInt()));
1✔
853
        }
854
        else if (root.name() == KXMLQLCVCWidgetBackgroundImage)
10✔
855
        {
856
            QString str = root.readElementText();
4✔
857
            if (str != KXMLQLCVCWidgetBackgroundImageNone)
2✔
858
                setBackgroundImage(m_doc->denormalizeComponentPath(str));
1✔
859
        }
860
        else if (root.name() == KXMLQLCVCWidgetFont)
8✔
861
        {
862
            QString str = root.readElementText();
12✔
863
            if (str != KXMLQLCVCWidgetFontDefault)
6✔
864
            {
865
                QFont font;
12✔
866
                font.fromString(str);
6✔
867
                setFont(font);
6✔
868
            }
869
        }
870
        else
871
        {
872
            qWarning() << Q_FUNC_INFO << "Unknown appearance tag:" << root.name();
2✔
873
            root.skipCurrentElement();
2✔
874
        }
875
    }
876

877
    return true;
8✔
878
}
879

880
QSharedPointer<QLCInputSource> VCWidget::getXMLInput(QXmlStreamReader &root)
7✔
881
{
882
    QXmlStreamAttributes attrs = root.attributes();
14✔
883

884
    quint32 uni = attrs.value(KXMLQLCVCWidgetInputUniverse).toString().toUInt();
7✔
885
    quint32 ch = attrs.value(KXMLQLCVCWidgetInputChannel).toString().toUInt();
7✔
886
    uchar min = 0, max = UCHAR_MAX;
7✔
887

888
    QSharedPointer<QLCInputSource>newSrc = QSharedPointer<QLCInputSource>(new QLCInputSource(uni, ch));
7✔
889
    if (attrs.hasAttribute(KXMLQLCVCWidgetInputLowerValue))
7✔
890
        min = uchar(attrs.value(KXMLQLCVCWidgetInputLowerValue).toString().toUInt());
×
891
    if (attrs.hasAttribute(KXMLQLCVCWidgetInputUpperValue))
7✔
892
        max = uchar(attrs.value(KXMLQLCVCWidgetInputUpperValue).toString().toUInt());
×
893

894
    newSrc->setRange(min, max);
7✔
895

896
    return newSrc;
14✔
897
}
898

899
bool VCWidget::loadXMLInput(QXmlStreamReader &root, const quint8 &id)
8✔
900
{
901
    if (root.device() == NULL || root.hasError())
8✔
902
        return false;
×
903

904
    if (root.name() != KXMLQLCVCWidgetInput)
8✔
905
        return false;
1✔
906

907
    QSharedPointer<QLCInputSource>newSrc = getXMLInput(root);
7✔
908

909
    setInputSource(newSrc, id);
7✔
910

911
    root.skipCurrentElement();
7✔
912

913
    return true;
7✔
914
}
915

916
QString VCWidget::loadXMLSources(QXmlStreamReader &root, quint8 sourceID)
6✔
917
{
918
    QString keyText;
6✔
919
    while (root.readNextStartElement())
14✔
920
    {
921
        if (root.name() == KXMLQLCVCWidgetInput)
8✔
922
        {
923
            loadXMLInput(root, sourceID);
4✔
924
        }
925
        else if (root.name() == KXMLQLCVCWidgetKey)
4✔
926
        {
927
            keyText = root.readElementText();
4✔
928
        }
929
        else
930
        {
931
            qWarning() << Q_FUNC_INFO << "Unknown source tag" << root.name().toString();
×
932
            root.skipCurrentElement();
×
933
        }
934
    }
935
    return keyText;
6✔
936
}
937

938
bool VCWidget::loadXMLInput(QXmlStreamReader &root, quint32* uni, quint32* ch) const
×
939
{
940
    if (root.name() != KXMLQLCVCWidgetInput)
×
941
    {
942
        qWarning() << Q_FUNC_INFO << "Input node not found!";
×
943
        return false;
×
944
    }
945
    else
946
    {
947
        QXmlStreamAttributes attrs = root.attributes();
×
948
        *uni = attrs.value(KXMLQLCVCWidgetInputUniverse).toString().toUInt();
×
949
        *ch = attrs.value(KXMLQLCVCWidgetInputChannel).toString().toUInt();
×
950
        root.skipCurrentElement();
×
951
    }
952

953
    return true;
×
954
}
955

956
bool VCWidget::saveXMLCommon(QXmlStreamWriter *doc)
7✔
957
{
958
    Q_ASSERT(doc != NULL);
7✔
959

960
    /* Caption */
961
    doc->writeAttribute(KXMLQLCVCCaption, caption());
7✔
962

963
    /* ID */
964
    if (id() != VCWidget::invalidId())
7✔
965
        doc->writeAttribute(KXMLQLCVCWidgetID, QString::number(id()));
×
966

967
    /* Page */
968
    if (page() != 0)
7✔
969
        doc->writeAttribute(KXMLQLCVCWidgetPage, QString::number(page()));
×
970

971
    return true;
7✔
972
}
973

974
bool VCWidget::saveXMLAppearance(QXmlStreamWriter *doc)
9✔
975
{
976
    Q_ASSERT(doc != NULL);
9✔
977

978
    QString str;
9✔
979

980
    /* VC appearance entry */
981
    doc->writeStartElement(KXMLQLCVCWidgetAppearance);
9✔
982

983
    /* Frame style */
984
    doc->writeTextElement(KXMLQLCVCFrameStyle, frameStyleToString(frameStyle()));
9✔
985

986
    /* Foreground color */
987
    if (hasCustomForegroundColor() == true)
9✔
988
        str.setNum(foregroundColor().rgb());
1✔
989
    else
990
        str = KXMLQLCVCWidgetColorDefault;
8✔
991
    doc->writeTextElement(KXMLQLCVCWidgetForegroundColor, str);
9✔
992

993
    /* Background color */
994
    if (hasCustomBackgroundColor() == true)
9✔
995
        str.setNum(backgroundColor().rgb());
1✔
996
    else
997
        str = KXMLQLCVCWidgetColorDefault;
8✔
998
    doc->writeTextElement(KXMLQLCVCWidgetBackgroundColor, str);
9✔
999

1000
    /* Background image */
1001
    if (backgroundImage().isEmpty() == false)
9✔
1002
        str = m_doc->normalizeComponentPath(m_backgroundImage);
1✔
1003
    else
1004
        str = KXMLQLCVCWidgetBackgroundImageNone;
8✔
1005
    doc->writeTextElement(KXMLQLCVCWidgetBackgroundImage, str);
9✔
1006

1007
    /* Font */
1008
    if (hasCustomFont() == true)
9✔
1009
        str = font().toString();
1✔
1010
    else
1011
        str = KXMLQLCVCWidgetFontDefault;
8✔
1012
    doc->writeTextElement(KXMLQLCVCWidgetFont, str);
9✔
1013

1014
    /* End the <Appearance> tag */
1015
    doc->writeEndElement();
9✔
1016

1017
    return true;
18✔
1018
}
1019

1020
bool VCWidget::saveXMLInput(QXmlStreamWriter *doc)
4✔
1021
{
1022
    return saveXMLInput(doc, inputSource());
4✔
1023
}
1024

1025
bool VCWidget::saveXMLInput(QXmlStreamWriter *doc,
12✔
1026
                            const QLCInputSource *src)
1027
{
1028
    Q_ASSERT(doc != NULL);
12✔
1029

1030
    if (src == NULL)
12✔
1031
        return false;
2✔
1032

1033
    if (src->isValid() == true)
10✔
1034
    {
1035
        doc->writeStartElement(KXMLQLCVCWidgetInput);
10✔
1036
        doc->writeAttribute(KXMLQLCVCWidgetInputUniverse, QString("%1").arg(src->universe()));
10✔
1037
        doc->writeAttribute(KXMLQLCVCWidgetInputChannel, QString("%1").arg(src->channel()));
10✔
1038
        if (src->lowerValue() != 0)
10✔
1039
            doc->writeAttribute(KXMLQLCVCWidgetInputLowerValue, QString::number(src->lowerValue()));
×
1040
        if (src->upperValue() != UCHAR_MAX)
10✔
1041
            doc->writeAttribute(KXMLQLCVCWidgetInputUpperValue, QString::number(src->upperValue()));
×
1042
        doc->writeEndElement();
10✔
1043
    }
1044

1045
    return true;
10✔
1046
}
1047

1048
bool VCWidget::saveXMLInput(QXmlStreamWriter *doc,
12✔
1049
                      QSharedPointer<QLCInputSource> const& src)
1050
{
1051
    return saveXMLInput(doc, src.data());
12✔
1052
}
1053

1054
bool VCWidget::saveXMLWindowState(QXmlStreamWriter *doc)
8✔
1055
{
1056
    Q_ASSERT(doc != NULL);
8✔
1057

1058
    /* Window state tag */
1059
    doc->writeStartElement(KXMLQLCWindowState);
8✔
1060

1061
    /* Visible status */
1062
    if (isVisible() == true)
8✔
1063
        doc->writeAttribute(KXMLQLCWindowStateVisible, KXMLQLCTrue);
2✔
1064
    else
1065
        doc->writeAttribute(KXMLQLCWindowStateVisible, KXMLQLCFalse);
6✔
1066

1067
    doc->writeAttribute(KXMLQLCWindowStateX, QString::number(x()));
8✔
1068
    doc->writeAttribute(KXMLQLCWindowStateY, QString::number(y()));
8✔
1069
    doc->writeAttribute(KXMLQLCWindowStateWidth, QString::number(width()));
8✔
1070
    doc->writeAttribute(KXMLQLCWindowStateHeight, QString::number(height()));
8✔
1071

1072
    doc->writeEndElement();
8✔
1073

1074
    return true;
8✔
1075
}
1076

1077
bool VCWidget::loadXMLWindowState(QXmlStreamReader &tag, int* x, int* y,
15✔
1078
                                  int* w, int* h, bool* visible)
1079
{
1080
    if (tag.device() == NULL || x == NULL || y == NULL || w == NULL || h == NULL ||
15✔
1081
            visible == NULL)
1082
        return false;
5✔
1083

1084
    if (tag.name() == KXMLQLCWindowState)
10✔
1085
    {
1086
        QXmlStreamAttributes attrs = tag.attributes();
9✔
1087
        *x = attrs.value(KXMLQLCWindowStateX).toString().toInt();
9✔
1088
        *y = attrs.value(KXMLQLCWindowStateY).toString().toInt();
9✔
1089
        *w = attrs.value(KXMLQLCWindowStateWidth).toString().toInt();
9✔
1090
        *h = attrs.value(KXMLQLCWindowStateHeight).toString().toInt();
9✔
1091

1092
        if (attrs.value(KXMLQLCWindowStateVisible).toString() == KXMLQLCTrue)
9✔
1093
            *visible = true;
8✔
1094
        else
1095
            *visible = false;
1✔
1096
        tag.skipCurrentElement();
9✔
1097

1098
        return true;
9✔
1099
    }
1100
    else
1101
    {
1102
        qWarning() << Q_FUNC_INFO << "Window state not found";
1✔
1103
        return false;
1✔
1104
    }
1105
}
1106

1107
/*****************************************************************************
1108
 * QLC+ Mode change
1109
 *****************************************************************************/
1110

1111
void VCWidget::setLiveEdit(bool liveEdit)
25✔
1112
{
1113
    if (m_doc->mode() == Doc::Design)
25✔
1114
        return;
25✔
1115

1116
    m_liveEdit = liveEdit;
×
1117

1118
    if (m_disableState)
×
1119
        setEnabled(m_liveEdit);
×
1120
    else
1121
        enableWidgetUI(!m_liveEdit);
×
1122

1123
    unsetCursor();
×
1124
    update();
×
1125
}
1126

1127
void VCWidget::cancelLiveEdit()
×
1128
{
1129
    m_liveEdit = false;
×
1130
}
×
1131

1132
void VCWidget::slotModeChanged(Doc::Mode mode)
66✔
1133
{
1134
    // make sure to exit from a 'deep' disable state
1135
    if (mode == Doc::Design)
66✔
1136
        setEnabled(true);
34✔
1137

1138
    /* Reset mouse cursor */
1139
    unsetCursor();
66✔
1140

1141
    /* Force an update to get rid of selection markers */
1142
    update();
66✔
1143
}
66✔
1144

1145
Doc::Mode VCWidget::mode() const
191✔
1146
{
1147
    Q_ASSERT(m_doc != NULL);
191✔
1148
    if (m_liveEdit)
191✔
1149
        return Doc::Design;
×
1150
    return m_doc->mode();
191✔
1151
}
1152

1153
/*****************************************************************************
1154
 * Widget menu
1155
 *****************************************************************************/
1156

1157
void VCWidget::invokeMenu(const QPoint& point)
×
1158
{
1159
    /* No point coming here if there is no VC instance */
1160
    VirtualConsole* vc = VirtualConsole::instance();
×
1161
    if (vc == NULL)
×
1162
        return;
×
1163

1164
    QMenu* menu = vc->editMenu();
×
1165
    Q_ASSERT(menu != NULL);
×
1166
    menu->exec(point);
×
1167
}
1168

1169
/*****************************************************************************
1170
 * Custom menu
1171
 *****************************************************************************/
1172

1173
QMenu* VCWidget::customMenu(QMenu* parentMenu)
3✔
1174
{
1175
    Q_UNUSED(parentMenu);
1176
    return NULL;
3✔
1177
}
1178

1179
/*****************************************************************************
1180
 * Widget move & resize
1181
 *****************************************************************************/
1182

1183
void VCWidget::resize(const QSize& size)
244✔
1184
{
1185
    QSize sz(size);
244✔
1186

1187
    // Force grid settings
1188
    sz.setWidth(size.width() - (size.width() % GRID_RESOLUTION));
244✔
1189
    sz.setHeight(size.height() - (size.height() % GRID_RESOLUTION));
244✔
1190

1191
    // Resize
1192
    QWidget::resize(sz);
244✔
1193
}
244✔
1194

1195
void VCWidget::move(const QPoint& point)
13✔
1196
{
1197
    QPoint pt(point);
13✔
1198

1199
    // Force grid settings
1200
    pt.setX(point.x() - (point.x() % GRID_RESOLUTION));
13✔
1201
    pt.setY(point.y() - (point.y() % GRID_RESOLUTION));
13✔
1202

1203
    // Don't move beyond left or right
1204
    if (pt.x() < 0)
13✔
1205
        pt.setX(0);
1✔
1206
    else if (pt.x() + rect().width() > parentWidget()->width())
12✔
1207
        pt.setX(parentWidget()->width() - rect().width());
1✔
1208

1209
    // Don't move beyond top or bottom
1210
    if (pt.y() < 0)
13✔
1211
        pt.setY(0);
1✔
1212
    else if (pt.y() + rect().height() > parentWidget()->height())
12✔
1213
        pt.setY(parentWidget()->height() - rect().height());
1✔
1214

1215
    // Move
1216
    QWidget::move(pt);
13✔
1217

1218
    m_doc->setModified();
13✔
1219
}
13✔
1220

1221
QPoint VCWidget::lastClickPoint() const
2✔
1222
{
1223
    return m_mousePressPoint;
2✔
1224
}
1225

1226
/*****************************************************************************
1227
 * Event handlers
1228
 *****************************************************************************/
1229

1230
void VCWidget::paintEvent(QPaintEvent* e)
32✔
1231
{
1232
    Q_UNUSED(e);
1233

1234
    /* No point coming here if there is no VC instance */
1235
    VirtualConsole* vc = VirtualConsole::instance();
32✔
1236
    if (vc == NULL)
32✔
1237
        return;
×
1238

1239
    QPainter painter(this);
64✔
1240

1241
    /* Draw frame according to style */
1242
    QStyleOptionFrame option;
64✔
1243
    option.initFrom(this);
32✔
1244

1245
    if (frameStyle() == KVCFrameStyleSunken)
32✔
1246
        option.state = QStyle::State_Sunken;
3✔
1247
    else if (frameStyle() == KVCFrameStyleRaised)
29✔
1248
        option.state = QStyle::State_Raised;
4✔
1249
    else
1250
        option.state = QStyle::State_None;
25✔
1251

1252
    if (mode() == Doc::Design)
32✔
1253
        option.state |= QStyle::State_Enabled;
28✔
1254

1255
    /* Draw a frame border if such is specified for this widget */
1256
    if (option.state != QStyle::State_None)
32✔
1257
        style()->drawPrimitive(QStyle::PE_Frame, &option, &painter, this);
29✔
1258

1259
    QWidget::paintEvent(e);
32✔
1260

1261
    /* Draw selection frame */
1262
    if (mode() == Doc::Design && vc->isWidgetSelected(this) == true)
32✔
1263
    {
1264
        /* Draw a dotted line around the widget */
1265
        QPen pen(Qt::DashLine);
8✔
1266
        pen.setColor(Qt::blue);
4✔
1267
        pen.setCapStyle(Qt::RoundCap);
4✔
1268
        pen.setWidth(0);
4✔
1269
        painter.setPen(pen);
4✔
1270
        painter.drawRect(0, 0, rect().width() - 1, rect().height() - 1);
4✔
1271

1272
        /* Draw a resize handle */
1273
        if (allowResize() == true)
4✔
1274
        {
1275
            QIcon icon(":/resize.png");
3✔
1276
            painter.drawPixmap(rect().width() - 16, rect().height() - 16,
3✔
1277
                               icon.pixmap(QSize(16, 16), QIcon::Normal, QIcon::On));
6✔
1278
        }
1279
    }
1280
}
1281

1282
void VCWidget::mousePressEvent(QMouseEvent* e)
2✔
1283
{
1284
    Q_ASSERT(e != NULL);
2✔
1285

1286
    if (mode() == Doc::Operate)
2✔
1287
    {
1288
        QWidget::mousePressEvent(e);
×
1289
        return;
×
1290
    }
1291

1292
    /* Perform widget de/selection in virtualconsole's selection buffer */
1293
    handleWidgetSelection(e);
2✔
1294

1295
    /* Resize mode */
1296
    if (m_resizeMode == true)
2✔
1297
    {
1298
        setMouseTracking(false);
×
1299
        m_resizeMode = false;
×
1300
    }
1301

1302
    /* Move, resize or context menu invocation */
1303
    if (e->button() & Qt::LeftButton || e->button() & Qt::MiddleButton)
2✔
1304
    {
1305
        /* Start moving or resizing based on where the click landed */
1306
        if (e->pos().x() > rect().width() - 10 && e->pos().y() > rect().height() - 10 && allowResize())
2✔
1307
        {
1308
            m_resizeMode = true;
×
1309
            setMouseTracking(true);
×
1310
            setCursor(QCursor(Qt::SizeFDiagCursor));
×
1311
        }
1312
        else
1313
        {
1314
            m_mousePressPoint = QPoint(e->pos().x(), e->pos().y());
2✔
1315
            setCursor(QCursor(Qt::SizeAllCursor));
2✔
1316
        }
1317
    }
1318
    else if (e->button() & Qt::RightButton)
×
1319
    {
1320
        /* Menu invocation */
1321
        m_mousePressPoint = QPoint(e->pos().x(), e->pos().y());
×
1322
        invokeMenu(mapToGlobal(e->pos()));
×
1323
    }
1324
}
1325

1326
void VCWidget::handleWidgetSelection(QMouseEvent* e)
3✔
1327
{
1328
    /* No point coming here if there is no VC */
1329
    VirtualConsole* vc = VirtualConsole::instance();
3✔
1330
    if (vc == NULL)
3✔
1331
        return;
×
1332

1333
    /* Widget selection logic (like in Qt Designer) */
1334
    if (e->button() == Qt::LeftButton)
3✔
1335
    {
1336
        if (e->modifiers() & Qt::ShiftModifier)
3✔
1337
        {
1338
            /* Toggle selection with LMB when shift is pressed */
1339
            bool selected = vc->isWidgetSelected(this);
×
1340
            vc->setWidgetSelected(this, !selected);
×
1341
        }
1342
        else
1343
        {
1344
            if (vc->isWidgetSelected(this) == false)
3✔
1345
            {
1346
                /* Select only this */
1347
                vc->clearWidgetSelection();
3✔
1348
                vc->setWidgetSelected(this, true);
3✔
1349
            }
1350
        }
1351
    }
1352
    else if (e->button() == Qt::RightButton)
×
1353
    {
1354
        if (vc->isWidgetSelected(this) == false)
×
1355
        {
1356
            /* Select only this */
1357
            vc->clearWidgetSelection();
×
1358
            vc->setWidgetSelected(this, true);
×
1359
        }
1360
    }
1361
}
1362

1363
void VCWidget::mouseReleaseEvent(QMouseEvent* e)
1✔
1364
{
1365
    if (mode() == Doc::Design)
1✔
1366
    {
1367
        unsetCursor();
1✔
1368
        m_resizeMode = false;
1✔
1369
        setMouseTracking(false);
1✔
1370
    }
1371
    else
1372
    {
1373
        QWidget::mouseReleaseEvent(e);
×
1374
    }
1375
}
1✔
1376

1377
void VCWidget::mouseDoubleClickEvent(QMouseEvent* e)
×
1378
{
1379
    if (mode() == Doc::Design)
×
1380
        editProperties();
×
1381
    else
1382
        QWidget::mouseDoubleClickEvent(e);
×
1383
}
×
1384

1385
void VCWidget::mouseMoveEvent(QMouseEvent* e)
2✔
1386
{
1387
    if (mode() == Doc::Design)
2✔
1388
    {
1389
        if (m_resizeMode == true)
2✔
1390
        {
1391
            QPoint p = mapToParent(e->pos());
×
1392
            resize(QSize(p.x() - x(), p.y() - y()));
×
1393
            m_doc->setModified();
×
1394
        }
1395
        else if (e->buttons() & Qt::LeftButton || e->buttons() & Qt::MiddleButton)
2✔
1396
        {
1397
            QPoint p = mapToParent(e->pos());
2✔
1398
            p.setX(p.x() - m_mousePressPoint.x());
2✔
1399
            p.setY(p.y() - m_mousePressPoint.y());
2✔
1400

1401
            move(p);
2✔
1402
            m_doc->setModified();
2✔
1403
        }
1404
    }
1405
    else
1406
    {
1407
        QWidget::mouseMoveEvent(e);
×
1408
    }
1409
}
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