1
/*  This file is part of the KDE project
2
    Copyright (C) 2006-2007 Matthias Kretz <kretz@kde.org>
3
4
    This library is free software; you can redistribute it and/or
5
    modify it under the terms of the GNU Lesser General Public
6
    License as published by the Free Software Foundation; either
7
    version 2.1 of the License, or (at your option) version 3, or any
8
    later version accepted by the membership of KDE e.V. (or its
9
    successor approved by the membership of KDE e.V.), Nokia Corporation 
10
    (or its successors, if any) and the KDE Free Qt Foundation, which shall
11
    act as a proxy defined in Section 6 of version 3 of the license.
12
13
    This library is distributed in the hope that it will be useful,
14
    but WITHOUT ANY WARRANTY; without even the implied warranty of
15
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16
    Lesser General Public License for more details.
17
18
    You should have received a copy of the GNU Lesser General Public 
19
    License along with this library.  If not, see <http://www.gnu.org/licenses/>.
20
21
*/
22
23
#include "objectdescriptionmodel.h"
24
#include "objectdescriptionmodel_p.h"
25
#include "phonondefs_p.h"
26
#include "platform_p.h"
27
#include <QtCore/QList>
28
#include "objectdescription.h"
29
#include "phononnamespace_p.h"
30
#include <QtCore/QMimeData>
31
#include <QtCore/QStringList>
32
#include <QtGui/QIcon>
33
#include "factory_p.h"
34
35
QT_BEGIN_NAMESPACE
36
37
#ifndef QT_NO_PHONON_OBJECTDESCRIPTIONMODEL
38
39
40
static const uint qt_meta_data_Phonon__ObjectDescriptionModel[] = {
41
42
 // content:
43
       1,       // revision
44
       0,       // classname
45
       0,    0, // classinfo
46
       0,    0, // methods
47
       0,    0, // properties
48
       0,    0, // enums/sets
49
50
       0        // eod
51
};
52
53
static const char qt_meta_stringdata_Phonon__ObjectDescriptionModel_AudioOutputDeviceType[]  = { "Phonon::AudioOutputDevice\0" };
54
static const char qt_meta_stringdata_Phonon__ObjectDescriptionModel_AudioCaptureDeviceType[] = { "Phonon::AudioCaptureDevice\0" };
55
static const char qt_meta_stringdata_Phonon__ObjectDescriptionModel_EffectType[]             = { "Phonon::EffectDescription\0" };
56
static const char qt_meta_stringdata_Phonon__ObjectDescriptionModel_AudioChannelType[]        = { "Phonon::AudioChannelDescription\0" };
57
static const char qt_meta_stringdata_Phonon__ObjectDescriptionModel_SubtitleType[]     = { "Phonon::SubtitleDescription\0" };
58
/*
59
static const char qt_meta_stringdata_Phonon__ObjectDescriptionModel_VideoOutputDeviceType[]  = { "Phonon::VideoOutputDevice\0" };
60
static const char qt_meta_stringdata_Phonon__ObjectDescriptionModel_VideoCaptureDeviceType[] = { "Phonon::VideoCaptureDevice\0" };
61
static const char qt_meta_stringdata_Phonon__ObjectDescriptionModel_AudioCodecType[]         = { "Phonon::AudioCodecDescription\0" };
62
static const char qt_meta_stringdata_Phonon__ObjectDescriptionModel_VideoCodecType[]         = { "Phonon::VideoCodecDescription\0" };
63
static const char qt_meta_stringdata_Phonon__ObjectDescriptionModel_ContainerFormatType[]    = { "Phonon::ContainerFormatDescription\0" };
64
static const char qt_meta_stringdata_Phonon__ObjectDescriptionModel_VisualizationType[]      = { "Phonon::VisualizationDescription\0" };
65
*/
66
67
namespace Phonon
68
{
69
70
template<> const QMetaObject ObjectDescriptionModel<AudioOutputDeviceType>::staticMetaObject = {
71
    { &QAbstractListModel::staticMetaObject, qt_meta_stringdata_Phonon__ObjectDescriptionModel_AudioOutputDeviceType,
72
      qt_meta_data_Phonon__ObjectDescriptionModel, 0 }
73
};
74
template<> const QMetaObject ObjectDescriptionModel<EffectType>::staticMetaObject = {
75
    { &QAbstractListModel::staticMetaObject, qt_meta_stringdata_Phonon__ObjectDescriptionModel_EffectType,
76
      qt_meta_data_Phonon__ObjectDescriptionModel, 0 }
77
};
78
template<> const QMetaObject ObjectDescriptionModel<AudioChannelType>::staticMetaObject = {
79
    { &QAbstractListModel::staticMetaObject, qt_meta_stringdata_Phonon__ObjectDescriptionModel_AudioChannelType,
80
      qt_meta_data_Phonon__ObjectDescriptionModel, 0 }
81
};
82
template<> const QMetaObject ObjectDescriptionModel<SubtitleType>::staticMetaObject = {
83
    { &QAbstractListModel::staticMetaObject, qt_meta_stringdata_Phonon__ObjectDescriptionModel_SubtitleType,
84
      qt_meta_data_Phonon__ObjectDescriptionModel, 0 }
85
};
86
template<> const QMetaObject ObjectDescriptionModel<AudioCaptureDeviceType>::staticMetaObject = {
87
    { &QAbstractListModel::staticMetaObject, qt_meta_stringdata_Phonon__ObjectDescriptionModel_AudioCaptureDeviceType,
88
      qt_meta_data_Phonon__ObjectDescriptionModel, 0 }
89
};
90
/*template<> const QMetaObject ObjectDescriptionModel<VideoOutputDeviceType>::staticMetaObject = {
91
    { &QAbstractListModel::staticMetaObject, qt_meta_stringdata_Phonon__ObjectDescriptionModel_VideoOutputDeviceType,
92
      qt_meta_data_Phonon__ObjectDescriptionModel, 0 }
93
};
94
template<> const QMetaObject ObjectDescriptionModel<VideoCaptureDeviceType>::staticMetaObject = {
95
    { &QAbstractListModel::staticMetaObject, qt_meta_stringdata_Phonon__ObjectDescriptionModel_VideoCaptureDeviceType,
96
      qt_meta_data_Phonon__ObjectDescriptionModel, 0 }
97
};
98
template<> const QMetaObject ObjectDescriptionModel<AudioCodecType>::staticMetaObject = {
99
    { &QAbstractListModel::staticMetaObject, qt_meta_stringdata_Phonon__ObjectDescriptionModel_AudioCodecType,
100
      qt_meta_data_Phonon__ObjectDescriptionModel, 0 }
101
};
102
template<> const QMetaObject ObjectDescriptionModel<VideoCodecType>::staticMetaObject = {
103
    { &QAbstractListModel::staticMetaObject, qt_meta_stringdata_Phonon__ObjectDescriptionModel_VideoCodecType,
104
      qt_meta_data_Phonon__ObjectDescriptionModel, 0 }
105
};
106
template<> const QMetaObject ObjectDescriptionModel<ContainerFormatType>::staticMetaObject = {
107
    { &QAbstractListModel::staticMetaObject, qt_meta_stringdata_Phonon__ObjectDescriptionModel_ContainerFormatType,
108
      qt_meta_data_Phonon__ObjectDescriptionModel, 0 }
109
};
110
template<> const QMetaObject ObjectDescriptionModel<VisualizationType>::staticMetaObject = {
111
    { &QAbstractListModel::staticMetaObject, qt_meta_stringdata_Phonon__ObjectDescriptionModel_VisualizationType,
112
      qt_meta_data_Phonon__ObjectDescriptionModel, 0 }
113
};*/
114
115
template<ObjectDescriptionType type>
116
const QMetaObject *ObjectDescriptionModel<type>::metaObject() const
117
{
118
    return &staticMetaObject;
119
}
120
121
template<ObjectDescriptionType type>
122
void *ObjectDescriptionModel<type>::qt_metacast(const char *_clname)
123
{
124
    if (!_clname) {
125
        return 0;
126
    }
127
    if (!strcmp(_clname, ObjectDescriptionModel<type>::staticMetaObject.className())) {
128
        return static_cast<void *>(const_cast<ObjectDescriptionModel<type> *>(this));
129
    }
130
    return QAbstractListModel::qt_metacast(_clname);
131
}
132
133
/*
134
template<ObjectDescriptionType type>
135
int ObjectDescriptionModel<type>::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
136
{
137
    return QAbstractListModel::qt_metacall(_c, _id, _a);
138
}
139
*/
140
141
int ObjectDescriptionModelData::rowCount(const QModelIndex &parent) const
142
{
143
    if (parent.isValid())
144
        return 0;
145
146
    return d->data.size();
147
}
148
149
QVariant ObjectDescriptionModelData::data(const QModelIndex &index, int role) const
150
{
151
    if (!index.isValid() || index.row() >= d->data.size() || index.column() != 0)
152
        return QVariant();
153
154
    switch(role)
155
    {
156
    case Qt::EditRole:
157
    case Qt::DisplayRole:
158
        return d->data.at(index.row())->name();
159
        break;
160
    case Qt::ToolTipRole:
161
        return d->data.at(index.row())->description();
162
        break;
163
    case Qt::DecorationRole:
164
        {
165
            QVariant icon = d->data.at(index.row())->property("icon");
166
            if (icon.isValid()) {
167
                if (icon.type() == QVariant::String) {
168
                    return Platform::icon(icon.toString());
169
                } else if (icon.type() == QVariant::Icon) {
170
                    return icon;
171
                }
172
            }
173
        }
174
        return QVariant();
175
    default:
176
        return QVariant();
177
}
178
}
179
180
Qt::ItemFlags ObjectDescriptionModelData::flags(const QModelIndex &index) const
181
{
182
    if(!index.isValid() || index.row() >= d->data.size() || index.column() != 0) {
183
        return Qt::ItemIsDropEnabled;
184
    }
185
186
    QVariant available = d->data.at(index.row())->property("available");
187
    if (available.isValid() && available.type() == QVariant::Bool && !available.toBool()) {
188
        return Qt::ItemIsSelectable | Qt::ItemIsDragEnabled;
189
    }
190
    return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled;
191
}
192
193
QList<int> ObjectDescriptionModelData::tupleIndexOrder() const
194
{
195
    QList<int> ret;
196
    for (int i = 0; i < d->data.size(); ++i) {
197
        ret.append(d->data.at(i)->index());
198
    }
199
    return ret;
200
}
201
202
int ObjectDescriptionModelData::tupleIndexAtPositionIndex(int positionIndex) const
203
{
204
    return d->data.at(positionIndex)->index();
205
}
206
207
QMimeData *ObjectDescriptionModelData::mimeData(ObjectDescriptionType type, const QModelIndexList &indexes) const
208
{
209
    QMimeData *mimeData = new QMimeData;
210
    QByteArray encodedData;
211
    QDataStream stream(&encodedData, QIODevice::WriteOnly);
212
    QModelIndexList::const_iterator end = indexes.constEnd();
213
    QModelIndexList::const_iterator index = indexes.constBegin();
214
    for(; index!=end; ++index) {
215
        if ((*index).isValid()) {
216
            stream << d->data.at((*index).row())->index();
217
        }
218
    }
219
    //pDebug() << Q_FUNC_INFO << "setting mimeData to" << mimeTypes(type).first() << "=>" << encodedData.toHex();
220
    mimeData->setData(mimeTypes(type).first(), encodedData);
221
    return mimeData;
222
}
223
224
void ObjectDescriptionModelData::moveUp(const QModelIndex &index)
225
{
226
    if (!index.isValid() || index.row() >= d->data.size() || index.row() < 1 || index.column() != 0)
227
        return;
228
229
    emit d->model->layoutAboutToBeChanged();
230
    QModelIndex above = index.sibling(index.row() - 1, index.column());
231
    d->data.swap(index.row(), above.row());
232
    QModelIndexList from, to;
233
    from << index << above;
234
    to << above << index;
235
    d->model->changePersistentIndexList(from, to);
236
    emit d->model->layoutChanged();
237
}
238
239
void ObjectDescriptionModelData::moveDown(const QModelIndex &index)
240
{
241
    if (!index.isValid() || index.row() >= d->data.size() - 1 || index.column() != 0)
242
        return;
243
244
    emit d->model->layoutAboutToBeChanged();
245
    QModelIndex below = index.sibling(index.row() + 1, index.column());
246
    d->data.swap(index.row(), below.row());
247
    QModelIndexList from, to;
248
    from << index << below;
249
    to << below << index;
250
    d->model->changePersistentIndexList(from, to);
251
    emit d->model->layoutChanged();
252
}
253
254
ObjectDescriptionModelData::ObjectDescriptionModelData(QAbstractListModel *model)
255
    : d(new ObjectDescriptionModelDataPrivate(model))
256
{
257
}
258
259
ObjectDescriptionModelData::~ObjectDescriptionModelData()
260
{
261
    delete d;
262
}
263
264
void ObjectDescriptionModelData::setModelData(const QList<QExplicitlySharedDataPointer<ObjectDescriptionData> > &newData)
265
{
266
    d->data = newData;
267
    d->model->reset();
268
}
269
270
QList<QExplicitlySharedDataPointer<ObjectDescriptionData> > ObjectDescriptionModelData::modelData() const
271
{
272
    return d->data;
273
}
274
275
QExplicitlySharedDataPointer<ObjectDescriptionData> ObjectDescriptionModelData::modelData(const QModelIndex &index) const
276
{
277
    if (!index.isValid() || index.row() >= d->data.size() || index.column() != 0) {
278
        return QExplicitlySharedDataPointer<ObjectDescriptionData>(new ObjectDescriptionData(0));
279
    }
280
    return d->data.at(index.row());
281
}
282
283
Qt::DropActions ObjectDescriptionModelData::supportedDropActions() const
284
{
285
    //pDebug() << Q_FUNC_INFO;
286
    return Qt::MoveAction;
287
}
288
289
bool ObjectDescriptionModelData::dropMimeData(ObjectDescriptionType type, const QMimeData *data, Qt::DropAction action,
290
        int row, int column, const QModelIndex &parent)
291
{
292
    Q_UNUSED(action);
293
    Q_UNUSED(column);
294
    Q_UNUSED(parent);
295
    //pDebug() << Q_FUNC_INFO << data << action << row << column << parent;
296
297
    QString format = mimeTypes(type).first();
298
    if (!data->hasFormat(format)) {
299
        return false;
300
    }
301
302
    if (row == -1) {
303
        row = d->data.size();
304
    }
305
306
    QByteArray encodedData = data->data(format);
307
    QDataStream stream(&encodedData, QIODevice::ReadOnly);
308
    QList<QExplicitlySharedDataPointer<ObjectDescriptionData> > toInsert;
309
    while (!stream.atEnd()) {
310
        int otherIndex;
311
        stream >> otherIndex;
312
        ObjectDescriptionData *obj = ObjectDescriptionData::fromIndex(type, otherIndex);
313
314
        if (obj->isValid()) {
315
            toInsert << QExplicitlySharedDataPointer<ObjectDescriptionData>(obj);
316
        } else {
317
            delete obj;
318
        }
319
    }
320
    d->model->beginInsertRows(QModelIndex(), row, row + toInsert.size() - 1);
321
    for (int i = 0 ; i < toInsert.count(); ++i) {
322
        d->data.insert(row, toInsert.at(i));
323
    }
324
    d->model->endInsertRows();
325
    return true;
326
}
327
328
329
bool ObjectDescriptionModelData::removeRows(int row, int count, const QModelIndex &parent)
330
{
331
    //pDebug() << Q_FUNC_INFO << row << count << parent;
332
    if (parent.isValid() || row + count > d->data.size()) {
333
        return false;
334
    }
335
    d->model->beginRemoveRows(parent, row, row + count - 1);
336
    for (;count > 0; --count) {
337
        d->data.removeAt(row);
338
    }
339
    d->model->endRemoveRows();
340
    return true;
341
}
342
343
/*
344
template<ObjectDescriptionType type>
345
bool ObjectDescriptionModel<type>::insertRows(int row, int count, const QModelIndex &parent)
346
{
347
    pDebug() << Q_FUNC_INFO << row << count << parent;
348
    if (parent.isValid() || row < 0 || row > d->data.size()) {
349
        return false;
350
    }
351
    beginInsertRows(parent, row, row + count - 1);
352
    for (;count > 0; --count) {
353
        d->data.insert(row, ObjectDescription<type>());
354
    }
355
    endInsertRows();
356
    return true;
357
}
358
*/
359
360
QStringList ObjectDescriptionModelData::mimeTypes(ObjectDescriptionType type) const
361
{
362
    return QStringList(QLatin1String("application/x-phonon-objectdescription") + QString::number(static_cast<int>(type)));
363
}
364
365
#if !defined(Q_CC_MSVC) || _MSC_VER > 1300 || defined(Q_CC_INTEL) || defined(Q_CC_MINGW)
366
#define INSTANTIATE_META_FUNCTIONS(type) \
367
template const QMetaObject *ObjectDescriptionModel<type>::metaObject() const; \
368
template void *ObjectDescriptionModel<type>::qt_metacast(const char *)
369
370
INSTANTIATE_META_FUNCTIONS(AudioOutputDeviceType);
371
INSTANTIATE_META_FUNCTIONS(AudioCaptureDeviceType);
372
INSTANTIATE_META_FUNCTIONS(EffectType);
373
INSTANTIATE_META_FUNCTIONS(AudioChannelType);
374
INSTANTIATE_META_FUNCTIONS(SubtitleType);
375
#endif
376
/*INSTANTIATE_META_FUNCTIONS(VideoOutputDeviceType);
377
INSTANTIATE_META_FUNCTIONS(VideoCaptureDeviceType);
378
INSTANTIATE_META_FUNCTIONS(AudioCodecType);
379
INSTANTIATE_META_FUNCTIONS(VideoCodecType);
380
INSTANTIATE_META_FUNCTIONS(ContainerFormatType);
381
INSTANTIATE_META_FUNCTIONS(VisualizationType);
382
*/
383
} // namespace Phonon
384
385
#endif //QT_NO_PHONON_OBJECTDESCRIPTIONMODEL
386
387
QT_END_NAMESPACE