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

mcallegari / qlcplus / 13633248611

03 Mar 2025 02:31PM UTC coverage: 31.871% (+0.4%) from 31.5%
13633248611

push

github

web-flow
actions: add chrpath to profile

14689 of 46089 relevant lines covered (31.87%)

26426.11 hits per line

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

0.0
/ui/src/cuestackmodel.cpp
1
/*
2
  Q Light Controller Plus
3
  cuestackmodel.cpp
4

5
  Copyright (c) Heikki Junnila
6
                Massimo Callegari
7

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

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

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

21
#include <QXmlStreamReader>
22
#include <QXmlStreamWriter>
23
#include <QApplication>
24
#include <QMimeData>
25
#include <QPalette>
26
#include <QBuffer>
27
#include <QBrush>
28
#include <QDebug>
29
#include <QIcon>
30

31
#include "cuestackmodel.h"
32
#include "cuestack.h"
33
#include "function.h"
34

35
#define MIMEDATA_ROOT       QString("MimeData")
36
#define MIMEDATA_DRAGINDEX  QString("DragIndex")
37

38
CueStackModel::CueStackModel(QObject* parent)
×
39
    : QAbstractItemModel(parent)
40
    , m_cueStack(NULL)
×
41
{
42
}
×
43

44
CueStackModel::~CueStackModel()
×
45
{
46
}
×
47

48
void CueStackModel::setCueStack(CueStack* cs)
×
49
{
50
    //qDebug() << Q_FUNC_INFO << "old:" << (void*)m_cueStack << "new:" << (void*) cs;
51

52
    if (m_cueStack != NULL)
×
53
    {
54
        // Don't attempt to remove anything if there's nothing to remove
55
        int last = m_cueStack->cues().size() - 1;
×
56
        if (last >= 0)
×
57
            beginRemoveRows(QModelIndex(), 0, last);
×
58

59
        disconnect(m_cueStack, SIGNAL(added(int)), this, SLOT(slotAdded(int)));
×
60
        disconnect(m_cueStack, SIGNAL(removed(int)), this, SLOT(slotRemoved(int)));
×
61
        disconnect(m_cueStack, SIGNAL(changed(int)), this, SLOT(slotChanged(int)));
×
62
        disconnect(m_cueStack, SIGNAL(currentCueChanged(int)), this, SLOT(slotCurrentCueChanged(int)));
×
63
        m_cueStack = NULL;
×
64

65
        if (last >= 0)
×
66
            endRemoveRows();
×
67
    }
68

69
    if (cs != NULL)
×
70
    {
71
        // Don't attempt to insert anything if there's nothing to insert
72
        if (cs->cues().size() > 0)
×
73
            beginInsertRows(QModelIndex(), 0, cs->cues().size() - 1);
×
74
        m_cueStack = cs;
×
75
        connect(m_cueStack, SIGNAL(added(int)), this, SLOT(slotAdded(int)));
×
76
        connect(m_cueStack, SIGNAL(removed(int)), this, SLOT(slotRemoved(int)));
×
77
        connect(m_cueStack, SIGNAL(changed(int)), this, SLOT(slotChanged(int)));
×
78
        connect(m_cueStack, SIGNAL(currentCueChanged(int)), this, SLOT(slotCurrentCueChanged(int)));
×
79
        if (cs->cues().size() > 0)
×
80
            endInsertRows();
×
81
    }
82
}
×
83

84
CueStack* CueStackModel::cueStack() const
×
85
{
86
    return m_cueStack;
×
87
}
88

89
/****************************************************************************
90
 * CueStack slots
91
 ****************************************************************************/
92

93
void CueStackModel::slotAdded(int index)
×
94
{
95
    Q_ASSERT(m_cueStack != NULL);
96
    beginInsertRows(QModelIndex(), index, index);
×
97
    endInsertRows();
×
98
}
×
99

100
void CueStackModel::slotRemoved(int index)
×
101
{
102
    Q_ASSERT(m_cueStack != NULL);
103
    beginRemoveRows(QModelIndex(), index, index);
×
104
    endRemoveRows();
×
105
}
×
106

107
void CueStackModel::slotChanged(int index)
×
108
{
109
    Q_ASSERT(m_cueStack != NULL);
110
    emit dataChanged(createIndex(index, 0, quintptr(0)), createIndex(index, 1, quintptr(0)));
×
111
}
×
112

113
void CueStackModel::slotCurrentCueChanged(int index)
×
114
{
115
    emit dataChanged(createIndex(index, 0, quintptr(0)), createIndex(index, 1, quintptr(0)));
×
116
}
×
117

118
/****************************************************************************
119
 * QAbstractItemModel
120
 ****************************************************************************/
121

122
int CueStackModel::columnCount(const QModelIndex& index) const
×
123
{
124
    Q_UNUSED(index);
125
    return CueStackModel::ColumnCount;
×
126
}
127

128
QVariant CueStackModel::headerData(int section, Qt::Orientation orientation, int role) const
×
129
{
130
    if (role != Qt::DisplayRole || orientation != Qt::Horizontal)
×
131
        return QVariant();
132

133
    switch(section)
×
134
    {
135
    case IndexColumn:
×
136
        return tr("Number");
×
137
    case FadeInColumn:
×
138
        return tr("Fade In");
×
139
    case FadeOutColumn:
×
140
        return tr("Fade Out");
×
141
    case DurationColumn:
×
142
        return tr("Duration");
×
143
    case NameColumn:
×
144
        return tr("Cue");
×
145
    default:
146
        return QVariant();
147
    }
148
}
149

150
QModelIndex CueStackModel::index(int row, int column, const QModelIndex& parent) const
×
151
{
152
    if (m_cueStack == NULL || parent.isValid() == true) // No parents
×
153
        return QModelIndex();
154
    else
155
        return createIndex(row, column, quintptr(0));
×
156
}
157

158
QModelIndex CueStackModel::parent(const QModelIndex& index) const
×
159
{
160
    Q_UNUSED(index);
161
    return QModelIndex();
×
162
}
163

164
int CueStackModel::rowCount(const QModelIndex& parent) const
×
165
{
166
    if (m_cueStack == NULL || parent.isValid() == true) // No parents
×
167
        return 0;
168
    else
169
        return m_cueStack->cues().size();
×
170
}
171

172
QVariant CueStackModel::data(const QModelIndex& index, int role) const
×
173
{
174
    if (m_cueStack == NULL)
×
175
        return QVariant();
176

177
    QVariant var;
178
    if (role == Qt::DisplayRole || role == Qt::ToolTipRole)
×
179
    {
180
        switch (index.column())
×
181
        {
182
        case IndexColumn:
183
            var = QVariant(index.row() + 1);
×
184
            break;
×
185
        case NameColumn:
×
186
            var = QVariant(m_cueStack->cues()[index.row()].name());
×
187
            break;
×
188
        case FadeInColumn:
×
189
        {
190
            uint ms = m_cueStack->cues()[index.row()].fadeInSpeed();
×
191
            if (ms > 0)
×
192
                var = QVariant(Function::speedToString(ms));
×
193
            else
194
                var = QVariant();
×
195
            break;
196
        }
197
        case FadeOutColumn:
×
198
        {
199
            uint ms = m_cueStack->cues()[index.row()].fadeOutSpeed();
×
200
            if (ms > 0)
×
201
                var = QVariant(Function::speedToString(ms));
×
202
            else
203
                var = QVariant();
×
204
            break;
205
        }
206
        case DurationColumn:
×
207
        {
208
            uint ms = m_cueStack->cues()[index.row()].duration();
×
209
            if (ms > 0)
×
210
                var = QVariant(Function::speedToString(ms));
×
211
            else
212
                var = QVariant();
×
213
            break;
214
        }
215
        default:
216
            var = QVariant();
×
217
            break;
×
218
        }
219
    }
220
    else if (role == Qt::DecorationRole)
×
221
    {
222
        if (m_cueStack->currentIndex() == index.row() && index.column() == 0)
×
223
            var = QVariant(QIcon(":/current.png"));
×
224
    }
225

226
    return var;
227
}
×
228

229
QStringList CueStackModel::mimeTypes () const
×
230
{
231
    return QStringList() << QString("text/plain");
×
232
}
233

234
Qt::DropActions CueStackModel::supportedDropActions() const
×
235
{
236
    return Qt::MoveAction | Qt::CopyAction;
×
237
}
238

239
Qt::ItemFlags CueStackModel::flags(const QModelIndex &index) const
×
240
{
241
    Qt::ItemFlags defaultFlags = QAbstractItemModel::flags(index);
×
242
    if (index.isValid() == true)
243
        return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | defaultFlags;
244
    else
245
        return Qt::ItemIsDropEnabled | defaultFlags;
×
246
}
247

248
bool CueStackModel::dropMimeData(const QMimeData* data, Qt::DropAction action, int row,
×
249
                                 int column, const QModelIndex& parent)
250
{
251
    qDebug() << Q_FUNC_INFO;
252

253
    Q_UNUSED(row);
254
    Q_UNUSED(column);
255

256
    if (m_cueStack == NULL || action != Qt::MoveAction)
×
257
        return false;
258

259
    if (data->hasText() == true)
×
260
    {
261
        QBuffer buffer;
×
262
        buffer.setData(data->text().toLatin1());
×
263
        buffer.open(QIODevice::ReadOnly | QIODevice::Text);
×
264
        QXmlStreamReader doc(&buffer);
×
265
        doc.readNextStartElement();
×
266
        if (doc.device() != NULL && doc.atEnd() == false && doc.hasError() == false)
×
267
        {
268
            if (doc.name() != MIMEDATA_ROOT)
×
269
            {
270
                qWarning() << Q_FUNC_INFO << "Invalid MIME data";
×
271
                return false;
×
272
            }
273

274
            // Dig the drag index from the XML
275
            int dragIndex = doc.attributes().value(MIMEDATA_DRAGINDEX).toString().toInt();
×
276
            int index = parent.row();
277
            if (dragIndex < index)
×
278
                index += 1; // Moving items from above drop index
×
279

280
            // Insert each dropped Cue as a new Cue since the originals are in fact
281
            // removed in removeRows().
282
            while (doc.readNextStartElement())
×
283
            {
284
                Cue cue;
×
285
                if (cue.loadXML(doc) == true)
×
286
                {
287
                    m_cueStack->insertCue(index, cue);
×
288
                    index++; // Shift insertion point forwards
×
289
                }
290
            }
×
291
        }
292

293
        return true;
×
294
    }
×
295
    else
296
    {
297
        return false;
298
    }
299
}
300

301
QMimeData* CueStackModel::mimeData(const QModelIndexList& indexes) const
×
302
{
303
    qDebug() << Q_FUNC_INFO << indexes;
304

305
    if (m_cueStack == NULL || indexes.size() == 0)
×
306
        return NULL;
307

308
    // MIME data is essentially a bunch of XML "Cue" entries (plus drag index)
309
    QBuffer buffer;
×
310
    buffer.open(QIODevice::WriteOnly | QIODevice::Text);
×
311
    QXmlStreamWriter doc(&buffer);
×
312
    doc.writeStartElement(MIMEDATA_ROOT);
×
313
    doc.writeAttribute(MIMEDATA_DRAGINDEX, QString::number(indexes.first().row()));
×
314

315
    QSet <int> rows;
316
    foreach (QModelIndex index, indexes)
×
317
    {
318
        // $indexes contains all rows' columns but we want to store one row only once.
319
        // So, discard $index if it appears more than once.
320
        if (rows.contains(index.row()) == true)
×
321
            continue;
322
        else if (index.row() >= 0 && index.row() < m_cueStack->cues().size())
×
323
            m_cueStack->cues().at(index.row()).saveXML(&doc);
×
324
        rows << index.row();
×
325
    }
326

327
    QMimeData* data = new QMimeData;
×
328
    doc.writeEndElement();
×
329
    doc.setDevice(NULL);
×
330
    buffer.close();
×
331

332
    data->setText(QString(buffer.data()));
×
333
    return data;
334
}
×
335

336
bool CueStackModel::removeRows(int row, int count, const QModelIndex& parent)
×
337
{
338
    if (m_cueStack == NULL || parent.isValid() == true)
×
339
        return false;
340

341
    for (int i = 0; i < count; i++)
×
342
        m_cueStack->removeCue(row);
×
343

344
    return true;
345
}
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